Copepod Collection
Copepods were collected at approximately weekly intervals from Lake
Champlain (Burlington Fishing Pier). Plankton was collected from the top
3 meters using a 250 um mesh net.
# Lake Champlain near Burlington, VT
siteNumber = "04294500"
ChamplainInfo = readNWISsite(siteNumber)
parameterCd = "00010"
startDate = "2023-01-01"
endDate = ""
#statCd = c("00001", "00002","00003", "00011") # 1 - max, 2 - min, 3 = mean
# Constructs the URL for the data wanted then downloads the data
url = constructNWISURL(siteNumbers = siteNumber, parameterCd = parameterCd,
startDate = startDate, endDate = endDate, service = "uv")
raw_temps = importWaterML1(url, asDateTime = T) %>%
mutate("date" = as.Date(dateTime)) %>%
select(dateTime, tz_cd, date, degC = X_00010_00000)
temp_data = raw_temps %>%
select(date, "temp" = degC)
Collections began in late May 2023. Several gaps are present, but
collections have continued at roughly weekly intervals since then.
Copepods from 42 collections were used to make a total of 1130 thermal
limit measurements. Over this time period, collection temperatures
ranged from 2.5 to 26.5°C.
There is substantial variation in thermal limits across the species
collected. There is also some degree of variation within the species,
with thermal limits increasing slightly during the summer.
## Daily values for the period examined by dataset
collection_conditions = temp_data %>%
ungroup() %>%
group_by(date) %>%
summarise(mean_temp = mean(temp),
med_temp = median(temp),
var_temp = var(temp),
min_temp = min(temp),
max_temp = max(temp)) %>%
mutate("range_temp" = max_temp - min_temp,
date = as.Date(date)) %>%
ungroup() %>%
filter(date >= (min(as.Date(full_data$collection_date)) - 7))
## Mean female thermal limits for each species, grouped by collection
species_summaries = full_data %>%
#filter(sex == "female") %>%
group_by(sp_name, collection_date, collection_temp) %>%
summarise("mean_ctmax" = mean(ctmax),
"sample_size" = n(),
"ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
"ctmax_var" = var(ctmax),
"mean_size" = mean(size),
"size_st_err" = (sd(size) / sqrt(sample_size)),
"size_var" = var(size)) %>%
ungroup() %>%
complete(sp_name, collection_date) %>%
arrange(desc(sample_size))
adult_summaries = full_data %>%
filter(sex == "female") %>%
group_by(sp_name, collection_date, collection_temp) %>%
summarise("mean_ctmax" = mean(ctmax),
"sample_size" = n(),
"ctmax_st_err" = (sd(ctmax) / sqrt(sample_size)),
"ctmax_var" = var(ctmax),
"mean_size" = mean(size),
"size_st_err" = (sd(size) / sqrt(sample_size)),
"size_var" = var(size)) %>%
ungroup() %>%
complete(sp_name, collection_date) %>%
arrange(desc(sample_size))
ggplot() +
geom_vline(data = unique(select(full_data, collection_date)),
aes(xintercept = as.Date(collection_date)),
colour = "grey90",
linewidth = 1) +
geom_line(data = collection_conditions,
aes(x = as.Date(date), y = mean_temp),
colour = "black",
linewidth = 2) +
# geom_errorbar(data = species_summaries,
# aes(x = as.Date(collection_date),
# ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
# colour = sp_name),
# position = position_dodge(width = 1),
# width = 5, linewidth = 1) +
# geom_point(data = adult_summaries,
# aes(x = as.Date(collection_date), y = mean_ctmax, colour = sp_name, size = sample_size)) +
geom_point(data = full_data,
aes(x = as.Date(collection_date), y = ctmax, colour = sp_name),
size = 2, position = position_jitter(width = 1, height = 0)) +
scale_colour_manual(values = species_cols) +
labs(x = "Date",
y = "Temperature (°C)",
colour = "Species",
size = "Sample Size") +
theme_matt() +
theme(legend.position = "right")

Size also varied, but primarily between rather than within
species.
ggplot() +
geom_vline(data = unique(select(full_data, collection_date)),
aes(xintercept = as.Date(collection_date)),
colour = "grey90",
linewidth = 1) +
geom_line(data = collection_conditions,
aes(x = as.Date(date), y = mean_temp),
colour = "black",
linewidth = 2) +
# geom_errorbar(data = species_summaries,
# aes(x = as.Date(collection_date),
# ymin = mean_ctmax - ctmax_st_err, ymax = mean_ctmax + ctmax_st_err,
# colour = sp_name),
# position = position_dodge(width = 1),
# width = 5, linewidth = 1) +
geom_point(data = adult_summaries,
aes(x = as.Date(collection_date), y = mean_size * 40, colour = sp_name, size = sample_size),
position = position_dodge(width = 1)) +
scale_colour_manual(values = species_cols) +
scale_y_continuous(
name = "Temperature", # Features of the first axis
sec.axis = sec_axis(~./40, name="Prosome Length (mm)"), # Add a second axis and specify its features
breaks = c(0,5,10,15,20,25,30)
) +
labs(x = "Date",
y = "Temperature (°C)",
colour = "Species") +
theme_matt() +
theme(legend.position = "right")

Shown below is CTmax and body size for the species with the most data
(Skistodiaptomus, L. minutus, L. sicilis, and
Epischura), plotted against the day of the year for each
sex/stage separately.
ctmax_feature = full_data %>%
mutate(doy = yday(collection_date)) %>%
filter(sp_name %in% c("Skistodiaptomus oregonensis", "Leptodiaptomus minutus", "Leptodiaptomus sicilis", "Epischura lacustris")) %>%
ggplot(aes(x = as.Date(collection_date), y = ctmax, colour = sp_name)) +
facet_grid(sp_name~sex) +
geom_point() +
scale_colour_manual(values = species_cols) +
labs(x = "Day of the Year",
y = "CTmax (°C)") +
theme_matt_facets() +
theme(axis.text.x = element_text(angle = 300, hjust = 0, vjust = 0.5),
legend.position = "none")
size_feature = full_data %>%
mutate(doy = yday(collection_date)) %>%
filter(sp_name %in% c("Skistodiaptomus oregonensis", "Leptodiaptomus minutus", "Leptodiaptomus sicilis", "Epischura lacustris")) %>%
ggplot(aes(x = as.Date(collection_date), y = size, colour = sp_name)) +
facet_grid(sp_name~sex) +
geom_point() +
scale_colour_manual(values = species_cols) +
labs(x = "Day of the Year",
y = "Size (mm)") +
theme_matt_facets() +
theme(axis.text.x = element_text(angle = 300, hjust = 0, vjust = 0.5),
legend.position = "none")
ggarrange(ctmax_feature, size_feature, common.legend = T, legend = "none")

adult_summaries %>%
ungroup() %>%
mutate(collection_num = as.numeric(factor(collection_date))) %>%
group_by(collection_date) %>%
arrange(collection_date) %>%
select(sp_name, collection_date, collection_num, sample_size) %>%
mutate(sample_size = replace_na(sample_size, 0)) %>%
mutate(total = sum(sample_size),
percentage = sample_size / total,
collection_date = lubridate::as_date(collection_date)) %>%
ggplot(aes(x = collection_date, y = percentage, fill = sp_name)) +
geom_area() +
scale_fill_manual(values = species_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Species") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

pathogen_cols = c("no" = "grey95", "cloudy" = "honeydew3", "spot" = "antiquewhite3", "other" = "tomato3")
full_data %>%
select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>%
group_by() %>%
filter(sex != "juvenile") %>%
group_by(collection_date) %>%
count(pathogen) %>%
filter(pathogen != "uncertain") %>%
pivot_wider(id_cols = "collection_date",
names_from = pathogen,
values_from = n,
values_fill = 0) %>%
mutate(total = sum(no, cloudy, spot, other)) %>%
pivot_longer(cols = c(no, cloudy, spot, other),
names_to = "pathogen",
values_to = "count") %>%
mutate(percent = count/total,
collection_date = lubridate::as_date(collection_date),
pathogen = fct_relevel(pathogen, "no", "cloudy", "spot", "other")) %>%
ggplot(aes(x = collection_date, y = percent, fill = pathogen)) +
geom_area() +
scale_fill_manual(values = pathogen_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Pathogen") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

dev_eggs_cols = c("no" = "grey95", "yes" = "lightblue3")
full_data %>%
select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>%
group_by(sp_name) %>%
filter(sex != "juvenile") %>%
group_by(sp_name, collection_date) %>%
count(dev_eggs) %>%
filter(dev_eggs != "uncertain") %>%
pivot_wider(id_cols = c("collection_date", "sp_name"),
names_from = dev_eggs,
values_from = n,
values_fill = 0) %>%
mutate(total = sum(no, yes)) %>%
pivot_longer(cols = c(no, yes),
names_to = "dev_eggs",
values_to = "count") %>%
mutate(percent = count/total,
collection_date = lubridate::as_date(collection_date),
dev_eggs = fct_relevel(dev_eggs, "no", "yes")) %>%
ungroup() %>%
complete(collection_date, nesting(sp_name, dev_eggs), fill = list(percent = 1)) %>%
mutate(percent = if_else(is.na(total) & dev_eggs == "yes", 0, percent)) %>%
ggplot(aes(x = collection_date, y = percent, fill = dev_eggs)) +
facet_wrap(sp_name~., ncol = 1) +
geom_area() +
scale_fill_manual(values = dev_eggs_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Developing \nEggs") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

lipid_cols = c("no" = "grey95", "yes" = "sienna2")
full_data %>%
select(collection_date, dev_eggs, pathogen, lipids, sp_name, sex) %>%
group_by(sp_name) %>%
filter(sex != "juvenile") %>%
group_by(sp_name, collection_date) %>%
count(lipids) %>%
filter(lipids != "uncertain") %>%
pivot_wider(id_cols = c("collection_date", "sp_name"),
names_from = lipids,
values_from = n,
values_fill = 0) %>%
mutate(total = sum(no, yes)) %>%
pivot_longer(cols = c(no, yes),
names_to = "lipids",
values_to = "count") %>%
mutate(percent = count/total,
collection_date = lubridate::as_date(collection_date),
lipids = fct_relevel(lipids, "no", "yes")) %>%
ungroup() %>%
complete(collection_date, nesting(sp_name, lipids), fill = list(percent = 1)) %>%
mutate(percent = if_else(is.na(total) & lipids == "yes", 0, percent)) %>%
ggplot(aes(x = collection_date, y = percent, fill = lipids)) +
facet_wrap(sp_name~., ncol = 1) +
geom_area() +
scale_fill_manual(values = lipid_cols) +
scale_y_continuous(breaks = c(0,1)) +
labs(x = "Collection Date",
y = "Proportion",
fill = "Lipids\nPresent") +
theme_minimal(base_size = 20) +
theme(panel.grid = element_blank(),
axis.ticks = element_line())

Temperature Variability
Lake Champlain is highly seasonal, with both average temperatures and
temperature variability changing throughout the year. These patterns in
the experienced thermal environment may drive the observed variation in
copepod thermal limits. However, the time period affecting copepod
thermal limits is unknown. Depending the on the duration of time
considered, there are large changes in the experienced environment, in
particular regarding the temperature range and variance. Consider for
example three time periods: the day of collection, one week prior to
collection, and four weeks prior to collection. While the overall
pattern is similar, we can see that, unsurprisingly, considering longer
periods of time results in larger ranges and slightly changes the
pattern of variance experienced.
## Daily values
daily_temp_data = temp_data %>%
ungroup() %>%
group_by(date) %>%
summarise(mean_temp = mean(temp),
med_temp = median(temp),
var_temp = var(temp),
min_temp = min(temp),
max_temp = max(temp)) %>%
mutate("range_temp" = max_temp - min_temp)
day_prior_temp_data = temp_data %>%
ungroup() %>%
group_by(date) %>%
summarise(mean_temp = mean(temp),
med_temp = median(temp),
var_temp = var(temp),
min_temp = min(temp),
max_temp = max(temp)) %>%
mutate(date = date + 1) %>%
rename_with(.fn = ~ paste0("prior_day_", .x), .cols = c(-date))
daily_plot = daily_temp_data %>%
pivot_longer(cols = c(-date),
names_to = "parameter",
values_to = "temp") %>%
ggplot(aes(x = date, y = temp, colour = parameter)) +
geom_line(linewidth = 1) +
scale_colour_manual(values = c(
"mean_temp" = "olivedrab3",
"med_temp" = "seagreen3",
"max_temp" = "tomato",
"min_temp" = "dodgerblue",
"range_temp" = "goldenrod3",
"var_temp" = "darkgoldenrod1"
)) +
scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
ggtitle("Daily Values") +
labs(y = "Temperature (°C)",
x = "") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
## Defining the function to get predictor values for periods of different lengths
get_predictors = function(daily_values, raw_temp, n_days){
prefix = str_replace_all(xfun::numbers_to_words(n_days), pattern = " ", replacement = "-")
mean_values = daily_values %>%
ungroup() %>%
mutate(mean_max = slide_vec(.x = max_temp, .f = mean, .before = n_days, .complete = T),
mean_min = slide_vec(.x = min_temp, .f = mean, .before = n_days, .complete = T),
mean_range = slide_vec(.x = range_temp, .f = mean, .before = n_days, .complete = T)) %>%
select(date, mean_max, mean_min, mean_range) %>%
rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))
period_values = raw_temp %>%
mutate(mean = slide_index_mean(temp, i = date, before = days(n_days),
na_rm = T),
max = slide_index_max(temp, i = date, before = days(n_days),
na_rm = T),
min = slide_index_min(temp, i = date, before = days(n_days),
na_rm = T),
med = slide_index_dbl(temp, .i = date, .before = days(n_days),
na_rm = T, .f = median),
var = slide_index_dbl(temp, .i = date, .before = days(n_days),
.f = var),
range = max - min) %>%
select(-temp) %>%
distinct() %>%
rename_with( ~ paste(prefix, "day", .x, sep = "_"), .cols = c(-date))%>%
inner_join(mean_values, by = c("date")) %>%
drop_na()
return(period_values)
}
# ## Getting predictor variables for different periods
#
# ### Short (three days)
# three_day_temps = get_predictors(daily_values = daily_temp_data,
# raw_temp = temp_data,
# n_days = 3)
#
# ### ONE WEEK
week_temps = get_predictors(daily_values = daily_temp_data,
raw_temp = temp_data,
n_days = 7)
week_plot = week_temps %>%
pivot_longer(cols = c(-date),
names_to = "parameter",
values_to = "temp") %>%
filter(parameter %in% c("seven_day_mean",
"seven_day_med",
"seven_day_max",
"seven_day_min",
"seven_day_var",
"seven_day_range")) %>%
mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
ggplot(aes(x = date, y = temp, colour = parameter)) +
geom_line(linewidth = 1) +
scale_colour_manual(values = c(
"mean_temp" = "olivedrab3",
"med_temp" = "seagreen3",
"max_temp" = "tomato",
"min_temp" = "dodgerblue",
"range_temp" = "goldenrod3",
"var_temp" = "darkgoldenrod1"
)) +
scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
ggtitle("One Week") +
labs(y = "Temperature (°C)",
x = "") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
#
# ### TWO WEEKS
# two_week_temps = get_predictors(daily_values = daily_temp_data,
# raw_temp = temp_data,
# n_days = 14)
#
# two_week_plot = two_week_temps %>%
# pivot_longer(cols = c(-date),
# names_to = "parameter",
# values_to = "temp") %>%
# filter(parameter %in% c("fourteen_day_mean",
# "fourteen_day_med",
# "fourteen_day_max",
# "fourteen_day_min",
# "fourteen_day_var",
# "fourteen_day_range")) %>%
# mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
# ggplot(aes(x = date, y = temp, colour = parameter)) +
# geom_line(linewidth = 1) +
# scale_colour_manual(values = c(
# "mean_temp" = "olivedrab3",
# "med_temp" = "seagreen3",
# "max_temp" = "tomato",
# "min_temp" = "dodgerblue",
# "range_temp" = "goldenrod3",
# "var_temp" = "darkgoldenrod1"
# )) +
# scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
# ggtitle("Two Weeks") +
# labs(y = "Temperature (°C)",
# x = "") +
# theme_bw(base_size = 20) +
# theme(panel.grid = element_blank(),
# axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
#
# ### FOUR WEEKS
four_week_temps = get_predictors(daily_values = daily_temp_data,
raw_temp = temp_data,
n_days = 28)
four_week_plot = four_week_temps %>%
pivot_longer(cols = c(-date),
names_to = "parameter",
values_to = "temp") %>%
filter(parameter %in% c("twenty-eight_day_mean",
"twenty-eight_day_med",
"twenty-eight_day_max",
"twenty-eight_day_min",
"twenty-eight_day_var",
"twenty-eight_day_range")) %>%
mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
ggplot(aes(x = date, y = temp, colour = parameter)) +
geom_line(linewidth = 1) +
scale_colour_manual(values = c(
"mean_temp" = "olivedrab3",
"med_temp" = "seagreen3",
"max_temp" = "tomato",
"min_temp" = "dodgerblue",
"range_temp" = "goldenrod3",
"var_temp" = "darkgoldenrod1"
)) +
scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
ggtitle("Four Weeks") +
labs(y = "Temperature (°C)",
x = "") +
theme_bw(base_size = 20) +
theme(panel.grid = element_blank(),
axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
#
# ### EIGHT WEEKS
# eight_week_temps = get_predictors(daily_values = daily_temp_data,
# raw_temp = temp_data,
# n_days = 56)
#
# eight_week_plot = eight_week_temps %>%
# pivot_longer(cols = c(-date),
# names_to = "parameter",
# values_to = "temp") %>%
# filter(parameter %in% c("fifty-six_day_mean",
# "fifty-six_day_med",
# "fifty-six_day_max",
# "fifty-six_day_min",
# "fifty-six_day_var",
# "fifty-six_day_range")) %>%
# mutate(parameter = paste(word(parameter, start = 3, sep = fixed("_")), "_temp", sep = "")) %>%
# ggplot(aes(x = date, y = temp, colour = parameter)) +
# geom_line(linewidth = 1) +
# scale_colour_manual(values = c(
# "mean_temp" = "olivedrab3",
# "med_temp" = "seagreen3",
# "max_temp" = "tomato",
# "min_temp" = "dodgerblue",
# "range_temp" = "goldenrod3",
# "var_temp" = "darkgoldenrod1"
# )) +
# scale_x_continuous(breaks = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01"))) +
# ggtitle("Eight Weeks") +
# labs(y = "Temperature (°C)",
# x = "") +
# theme_bw(base_size = 20) +
# theme(panel.grid = element_blank(),
# axis.text.x = element_text(angle = 270, hjust = 0, vjust = 0.5))
#
ggarrange(daily_plot, week_plot, four_week_plot,
common.legend = T, nrow = 1, legend = "bottom")

The different time periods examined by this climate data highlights
that the relationship between minimum and maximum temperatures changes
based on the window examined. For example, minimum and maximum
temperatures experienced over weekly intervals are closely linked,
whereas there is a distinct seasonal cycle in the relationship between
minimum and maximum temperatures experienced over periods of four
weeks.
one_week_doy_data = week_temps %>%
mutate(doy = yday(date))
one_week_temp_circle = ggplot(one_week_doy_data, aes(x = seven_day_mean_max, y = seven_day_mean_min, colour = doy)) +
geom_point() +
scale_colour_gradient2(
high = "dodgerblue4",
mid = "coral2",
low = "dodgerblue4",
midpoint = 182.5) +
labs(x = "Max. Temp. (°C)",
y = "Min. Temp. (°C)") +
labs(x = "Max. Temp. (°C)",
y = "Min. Temp. (°C)") +
ggtitle("One Week") +
theme_matt()
four_week_doy_data = four_week_temps %>%
mutate(doy = yday(date))
four_week_temp_circle = ggplot(four_week_doy_data, aes(x = `twenty-eight_day_max`, y = `twenty-eight_day_min`, colour = doy)) +
geom_point() +
scale_colour_gradient2(
high = "dodgerblue4",
mid = "coral2",
low = "dodgerblue4",
midpoint = 182.5) +
labs(x = "Max. Temp. (°C)",
y = "Min. Temp. (°C)") +
ggtitle("Four Week") +
theme_matt()
ggarrange(one_week_temp_circle, four_week_temp_circle,
common.legend = T, legend = "bottom")

The thermal environment over any period of time may drive patterns in
thermal acclimation. To explore the potential effects of different
acclimation windows, we examined the correlation between thermal limits
and different representations of the thermal environment for different
periods of time. Shown below are the correlation coefficients for these
relationships. Each facet shows the relationship for a different
dimension of the thermal environment. Correlation coefficients are
plotted for different durations, for species that were collected more
than five times. Only data for mature female copepods was included.
We can see that, in general, copepods are responding to proximate
cues from the thermal environment, with correlations generally dropping
off substantially as acclimation window duration increases. An exception
is Epischura lacustris, which appears to be responding to
maximum temperatures experienced over a 20 day time period.
### Pulling predictors and measuring correlations for much finer timescales; 1-56 days
num_colls = full_data %>%
filter(sex == "female") %>%
select(collection_date, sp_name) %>%
distinct() %>%
count(sp_name) %>%
filter(n >= 5)
corr_vals = data.frame()
dur_vals = c(1:50)
for(i in dur_vals){
duration_temps = get_predictors(daily_values = daily_temp_data,
raw_temp = temp_data,
n_days = i) %>%
filter(date %in% as_date(unique(full_data$collection_date)))
corr_data = full_data %>%
filter(sp_name %in% num_colls$sp_name) %>%
filter(sex == "female") %>%
mutate(collection_date = as.Date(collection_date)) %>%
inner_join(duration_temps, join_by(collection_date == date)) %>%
pivot_longer(cols = c(collection_temp, contains("day_")),
values_to = "value",
names_to = "predictor") %>%
group_by(sp_name, predictor) %>%
summarise(correlation = cor.test(ctmax, value)$estimate,
p.value = cor.test(ctmax, value)$p.value,
ci_low = cor.test(ctmax, value)$conf.int[1],
ci_high = cor.test(ctmax, value)$conf.int[2],
.groups = "keep") %>%
filter(predictor != "collection_temp") %>%
mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig.")) %>%
separate(predictor, "_day_", into = c(NA, "parameter")) %>%
mutate(duration = i)
corr_vals = bind_rows(corr_vals, corr_data)
}
coll_corr = full_data %>%
filter(sp_name %in% num_colls$sp_name) %>%
filter(sex == "female") %>%
group_by(sp_name) %>%
summarise(correlation = cor.test(ctmax, collection_temp)$estimate,
p.value = cor.test(ctmax, collection_temp)$p.value,
ci_low = cor.test(ctmax, collection_temp)$conf.int[1],
ci_high = cor.test(ctmax, collection_temp)$conf.int[2]) %>%
mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig.")) %>%
mutate(duration = 0,
parameter = "coll_temp")
corr_vals = corr_vals %>%
mutate(duration = as.numeric(duration)) %>%
bind_rows(coll_corr)
corr_vals %>%
mutate(parameter = fct_relevel(parameter, c("min", "max", "range",
"mean", "med", "var",
"mean_min", "mean_max", "mean_range"))) %>%
ggplot(aes(x = duration, y = correlation, colour = sp_name)) +
facet_wrap(.~parameter) +
geom_hline(yintercept = 0) +
geom_point(size = 0.9) +
geom_line(linewidth = 1.5) +
scale_colour_manual(values = species_cols) +
labs(x = "Duration (days)",
y = "Correlation",
colour = "Species") +
theme_matt_facets()

Shown here are the top three factors for each species.
#
# corr_vals = full_data %>%
# filter(sp_name %in% num_colls$sp_name) %>%
# filter(sex == "female") %>%
# mutate(collection_date = as.Date(collection_date)) %>%
# full_join(temp_predictors, join_by(collection_date == date)) %>%
# pivot_longer(cols = c(collection_temp, mean_temp:tail(names(.), 1)),
# values_to = "value",
# names_to = "predictor") %>%
# group_by(sp_name, predictor) %>%
# summarise(correlation = cor.test(ctmax, value)$estimate,
# p.value = cor.test(ctmax, value)$p.value,
# ci_low = cor.test(ctmax, value)$conf.int[1],
# ci_high = cor.test(ctmax, value)$conf.int[2]) %>%
# mutate(sig = ifelse(p.value <0.05, "Sig.", "Non Sig."))
corr_vals %>%
filter(sig == "Sig.") %>%
drop_na(correlation) %>%
group_by(sp_name) %>%
arrange(desc(correlation)) %>%
slice_head(n = 3) %>%
select("Species" = sp_name, "Predictor" = parameter, "Duration" = duration, "Correlation" = correlation, "P-Value" = p.value) %>%
knitr::kable(align = "c")
| Epischura lacustris |
max |
20 |
0.8926416 |
0.0000000 |
| Epischura lacustris |
max |
19 |
0.8906963 |
0.0000000 |
| Epischura lacustris |
max |
21 |
0.8874924 |
0.0000000 |
| Leptodiaptomus minutus |
max |
6 |
0.7680372 |
0.0000000 |
| Leptodiaptomus minutus |
max |
7 |
0.7677621 |
0.0000000 |
| Leptodiaptomus minutus |
max |
8 |
0.7677149 |
0.0000000 |
| Leptodiaptomus sicilis |
range |
24 |
0.3375596 |
0.0000000 |
| Leptodiaptomus sicilis |
var |
21 |
0.3372144 |
0.0000000 |
| Leptodiaptomus sicilis |
range |
23 |
0.3368199 |
0.0000000 |
| Limnocalanus macrurus |
max |
8 |
0.5542854 |
0.0001397 |
| Limnocalanus macrurus |
max |
7 |
0.5539836 |
0.0001412 |
| Limnocalanus macrurus |
mean_min |
6 |
0.5530991 |
0.0001454 |
| Skistodiaptomus oregonensis |
max |
2 |
0.7964802 |
0.0000000 |
| Skistodiaptomus oregonensis |
max |
1 |
0.7903638 |
0.0000000 |
| Skistodiaptomus oregonensis |
mean_max |
2 |
0.7896567 |
0.0000000 |
Phenotypic variation (like acclimation of thermal limits) is a
physiological process. depending on the mechanistic underpinnings
(changes in HSP expression, etc.), the amount of time it takes for an
individual to acclimate may vary based on body size (larger species,
more cells, more time required to acclimate). Shown here is the duration
of the environmental acclimation window the copepods appear to be
responding to.
mean_sizes = full_data %>%
filter(sex == "female") %>%
group_by(sp_name) %>%
summarise(mean_size = mean(size, na.rm = T))
corr_vals %>%
group_by(sp_name) %>%
filter(correlation == max(correlation)) %>%
inner_join(mean_sizes, by = "sp_name") %>%
select(sp_name, duration, mean_size) %>%
ggplot(aes(x = mean_size, y = duration)) +
geom_point(aes(colour = sp_name),
size = 4) +
scale_colour_manual(values = species_cols) +
labs(x = "Mean Female Size (mm)",
y = "Acclimation Duration",
colour = "Species") +
theme_matt() +
theme(legend.position = "right")

Trait Variation
# ctmax_plot = full_data %>%
# mutate( #sp_name = str_replace(sp_name, pattern = " ",
# # replacement = "\n"),
# sp_name = fct_reorder(sp_name, ctmax, mean)) %>%
# ggplot(aes(y = sp_name, x = ctmax)) +
# geom_point(aes(colour= sp_name_sub),
# position = position_dodge(width = 0.3),
# size = 4) +
# scale_colour_manual(values = species_cols) +
# xlab(NULL) +
# labs(y = "",
# x = "CTmax (°C)",
# colour = "Group") +
# theme_matt() +
# theme(legend.position = "none")
#
# size_plot = full_data %>%
# mutate(sp_name = fct_reorder(sp_name, ctmax, mean)) %>%
# ggplot(aes(y = sp_name, x = size)) +
# geom_point(aes(colour= sp_name_sub),
# position = position_dodge(width = 0.3),
# size = 4) +
# scale_colour_manual(values = species_cols) +
# labs(x = "Prosome Length (mm)",
# y = "",
# colour = "Group") +
# guides(color = guide_legend(ncol = 1)) +
# theme_matt(base_size = ) +
# theme(legend.position = "right",
# axis.text.y = element_blank(),
# plot.margin = margin(0, 0, 0, 0,"cm"))
#
# trait_plot = ctmax_plot + size_plot
# trait_plot
Shown below are the clutch size distributions for the three
diaptomiid species, which produce egg sacs that allow for easy
quantification of fecundity.
full_data %>%
drop_na(fecundity) %>%
ggplot(aes(x = fecundity, fill = sp_name_sub)) +
facet_wrap(.~sp_name_sub, ncol = 1) +
geom_histogram(binwidth = 2) +
scale_fill_manual(values = species_cols) +
labs(x = "Fecundity (# Eggs)") +
theme_matt_facets() +
theme(legend.position = "none")

One of the main aims of this project is to examine the patterns and
processes driving variation in upper thermal limits across these species
of copepods.
Variation with temperature
We expect one of the primary drivers of copepod thermal limits to be
temperature. The correlation analysis has shown that the copepods are
generally (although not always) responding to the recent thermal
environment. Shown below are thermal limits, body size, and fecundity
values plotted against the temperature at the time of collection. Also
shown is warming tolerance, calculated as the difference between upper
thermal limit and the collection temperature.
We generally see an increase in thermal limits with increasing
collection temperature, a slight decrease in body size, and variable
relationships between temperature and fecundity. All species maintained
some degree of buffer between environmental temperatures and upper
thermal limits, but Epischura and L. minutus
approached their upper thermal limits during the warmest collections
during the summer.
ctmax_temp = ggplot(full_data, aes(x = collection_temp, y = ctmax, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
size_temp = ggplot(filter(full_data, sex != "juvenile"), aes(x = collection_temp, y = size, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "Length (mm)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
wt_temp = ggplot(full_data, aes(x = collection_temp, y = warming_tol, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "Warming Tolerance (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
eggs_temp = ggplot(full_data, aes(x = collection_temp, y = fecundity, colour = sp_name)) +
geom_smooth(method = "lm", linewidth = 3) +
geom_point(size = 3) +
labs(x = "Collection Temperature (°C)",
y = "Fecundity (# Eggs)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")
ggarrange(ctmax_temp, size_temp, wt_temp, eggs_temp,
common.legend = T, legend = "right")

full_data %>%
#filter(sex == "female") %>%
group_by(sp_name) %>% filter(n() > 5) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>%
ggplot(aes(x = collection_temp, y = ctmax, colour = sp_name)) +
facet_wrap(sp_name~.) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
labs(x = "Collection Temp. (°C)",
y = "CTmax (°C)") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "none")

Temperature dependence is relatively weak in L. sicilis,
especially at cooler temperatures. We will return to this feature later
in the report, but for now we will note that there are two size morphs
in this species, which appear to respond differently to decreases in
temperature. There are significant differences between the morphs and
how temperature affects CTmax.
morph_data = full_data %>%
filter(sex == "female" & sp_name == "Leptodiaptomus sicilis") %>%
mutate(morph = if_else(size > 0.89, "large", "small"))
ggplot(morph_data, aes(x = collection_temp, y = ctmax, colour = morph)) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = T, linewidth = 2) +
labs(x = "Collection Temp. (°C)",
y = "CTmax (°C)") +
theme_matt() +
theme(legend.position = "none")

morph.model = lm(data = morph_data,
ctmax ~ collection_temp * morph)
knitr::kable(car::Anova(morph.model, type = "III", test = "F"))
| (Intercept) |
11408.08883 |
1 |
4115.495182 |
0.0000000 |
| collection_temp |
114.78189 |
1 |
41.407839 |
0.0000000 |
| morph |
32.06480 |
1 |
11.567451 |
0.0007612 |
| collection_temp:morph |
12.77976 |
1 |
4.610331 |
0.0325732 |
| Residuals |
839.91130 |
303 |
NA |
NA |
#summary(morph.model)
#morph.em = emmeans::emmeans(morph.model, pairwise ~ morph)
#plot(morph.em)
Copepods spent several days in lab during experiments. Shown below
are the CTmax residuals (taken from a model of CTmax against collection
temperature) plotted against the time spent in lab before measurements
were made. Individual regressions are shown for the residuals against
days in lab for each collection. We can see clearly that thermal limits
are fairly stable over time.
ggplot(ctmax_resids, aes(x = days_in_lab, y = resids, colour = sp_name, group = collection_date)) +
facet_wrap(sp_name~.) +
geom_point(size = 4, alpha = 0.5) +
geom_smooth(method = "lm", se = F, linewidth = 1) +
#scale_x_continuous(breaks = c(0:5)) +
labs(x = "Days in lab",
y = "CTmax Residuals") +
scale_colour_manual(values = species_cols) +
theme_matt_facets() +
theme(legend.position = "none")

full.model = lme4::lmer(data = model_data,
ctmax ~ sex + temp_cent + size_cent +
(1 + days_in_lab + temp_cent + size_cent|sp_name))
car::Anova(full.model)
## Analysis of Deviance Table (Type II Wald chisquare tests)
##
## Response: ctmax
## Chisq Df Pr(>Chisq)
## sex 35.8919 2 1.608e-08 ***
## temp_cent 15.0021 1 0.0001074 ***
## size_cent 1.1636 1 0.2807102
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
fixed = fixef(full.model)
model_coefs = coefficients(full.model)$`sp_name` %>%
rownames_to_column(var = "species") %>%
separate(species, into = c("species"), sep = ":") %>%
select(species, "intercept" = "(Intercept)", temp_cent, size_cent, days_in_lab)
ggplot(model_coefs, aes(x = intercept, y = temp_cent)) +
geom_smooth(method = "lm", colour = "black") +
geom_point(aes(colour = species),
size = 6) +
scale_colour_manual(values = species_cols) +
labs(x = "Species Intercept",
y = "ARR") +
theme_matt() +
theme(legend.position = "right")

The term “acclimation response ratio” is often used to describe the
effect of temperature on thermal limits. The ARR is calculated as the
change in thermal limits per degree change in acclimation temperature.
For our data, we will estimate ARR as the slope of CTmax against
collection temperature. These slopes were taken from a regression of
CTmax against collection temperature and body size. Two different model
types were used, a simple linear regression and a mixed effects model.
The estimated ARR values were generally highly similar between the model
types used.
Sex and stage variation in thermal limits
Previous sections have generally lumped juvenile, female, and male
individuals together. There may be important stage- or sex-specific
differences in CTmax though. For several species, we have measurements
for individuals in different stages or of different sexes.
sex_sample_sizes = ctmax_resids %>%
group_by(sp_name, sex) %>%
summarise(num = n()) %>%
pivot_wider(id_cols = sp_name,
names_from = sex,
values_from = num,
values_fill = 0) %>%
select("Species" = sp_name, "Juvenile" = juvenile, "Female" = female, "Male" = male)
knitr::kable(sex_sample_sizes, align = "c")
| Epischura lacustris |
25 |
45 |
19 |
| Leptodiaptomus minutus |
11 |
219 |
35 |
| Leptodiaptomus sicilis |
31 |
307 |
89 |
| Limnocalanus macrurus |
2 |
42 |
38 |
| Osphranticum labronectum |
0 |
1 |
0 |
| Senecella calanoides |
3 |
20 |
8 |
| Skistodiaptomus oregonensis |
14 |
191 |
28 |
The female-male and female-juvenile comparisons show that there are
generally no differences in thermal limits between these groups.
ctmax_resids %>%
filter(sp_name %in% filter(sex_sample_sizes, Male > 0, Female > 0)$Species &
sex != "juvenile") %>%
ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) +
facet_wrap(sp_name~., ncol = 2) +
geom_smooth(method = "lm", se = F, linewidth = 1) +
geom_point(size = 3,
alpha = 0.5,
position = position_jitter(height = 0, width = 0.05)) +
labs(x = "Sex",
y = "CTmax Residuals") +
scale_colour_manual(values = species_cols) +
theme_bw(base_size = 18) +
theme(legend.position = "none",
panel.grid = element_blank())

ctmax_resids %>%
filter(sp_name %in% filter(sex_sample_sizes, Juvenile > 0 & Female > 0)$Species &
sex != "male") %>%
ggplot(aes(x = sex, y = resids, colour = sp_name, group = sp_name)) +
facet_wrap(sp_name~., ncol = 2) +
geom_smooth(method = "lm", se = F, linewidth = 1) +
geom_point(size = 3,
alpha = 0.5,
position = position_jitter(height = 0, width = 0.05)) +
labs(x = "Sex",
y = "CTmax (°C)") +
scale_colour_manual(values = species_cols) +
theme_bw(base_size = 18) +
theme(legend.position = "none",
panel.grid = element_blank())

Trait Correlations and Trade-offs
A relationship between size and upper thermal limits has been
suggested in a wide range of other taxa. Shown below are the measured
upper thermal limits plotted against prosome length. The overall
relationship (inclusive of all species) is shown as the black line in
the background. Regressions for each individual species are also shown.
Across the entire assemblage, there is a strong decrease in thermal
limits with increasing size.
full_data %>%
#filter(sex == "female") %>%
ggplot( aes(x = size, y = ctmax, colour = sp_name)) +
geom_smooth(data = full_data,
aes(x = size, y = ctmax),
method = "lm",
colour ="black",
linewidth = 2.5) +
geom_point(size = 2, alpha = 0.3) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
labs(x = "Length (mm)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

Shown here is the relationship for each species individually.
full_data %>%
#filter(sex == "female") %>%
group_by(sp_name) %>% filter(n() >2) %>% filter(!str_detect(sp_name, pattern = "kindti")) %>%
ggplot( aes(x = size, y = ctmax, colour = sp_name)) +
facet_wrap(sp_name~., scales = "free", nrow = 2) +
geom_point(size = 2, alpha = 0.8) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
labs(x = "Length (mm)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "none")

Shown below is the relationship between mean size and mean thermal
limits for females of each species. We see that larger species within
the community tend to have a lower thermal limit than smaller
species.
full_data %>%
group_by(sp_name, sex) %>%
summarize(mean_ctmax = mean(ctmax, na.rm = T),
mean_size = mean(size, na.rm = T)) %>%
#filter(sex == "female") %>%
ggplot(aes(x = mean_size, y = mean_ctmax)) +
geom_smooth(method = "lm", se = F, linewidth = 2, colour = "black") +
geom_point(aes(colour = sp_name, shape = sex),
size = 5) +
labs(x = "Length (mm)",
y = "CTmax (°C)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

Shown here is the relationship between fecundity and size, showing
the classic pattern of increasing egg production with increasing
size.
ctmax_resids %>%
drop_na(fecundity) %>%
ggplot(aes(x = size, y = fecundity, colour = sp_name)) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
geom_point(size = 2, alpha = 0.5) +
labs(x = "Prosome length (mm)",
y = "Fecundity (# Eggs)",
colour = "Species") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

Individuals may also allocate energy to different fitness related
traits, prioritizing reproductive output over environmental tolerance,
for example. Shown below is the relationship between CTmax residuals
(again, controlling for the effects of collection temperature) against
fecundity. We can see clearly that individuals with increased fecundity
are not decreasing thermal limits, suggesting that there is no energetic
trade-off between these traits.
ctmax_resids %>%
drop_na(fecundity) %>%
ggplot(aes(x = resids, y = fecundity, colour = sp_name)) +
geom_smooth(method = "lm", se = F, linewidth = 2) +
geom_point(size = 2, alpha = 0.5) +
labs(x = "CTmax Residuals",
y = "Fecundity (# Eggs)") +
scale_colour_manual(values = species_cols) +
theme_matt() +
theme(legend.position = "right")

fitness.model = lm(data = ctmax_resids,
fecundity ~ resids * sp_name)
car::Anova(fitness.model)
## Anova Table (Type II tests)
##
## Response: fecundity
## Sum Sq Df F value Pr(>F)
## resids 0.4 1 0.0225 0.880973
## sp_name 8192.7 2 251.1667 < 2.2e-16 ***
## resids:sp_name 200.2 2 6.1390 0.002436 **
## Residuals 4925.4 302
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
emmeans::emtrends(fitness.model, var = "resids","sp_name")
## sp_name resids.trend SE df lower.CL upper.CL
## Leptodiaptomus minutus 0.51867 0.282 302 -0.0365 1.074
## Leptodiaptomus sicilis -0.00361 0.240 302 -0.4751 0.468
## Skistodiaptomus oregonensis -1.21286 0.406 302 -2.0120 -0.414
##
## Confidence level used: 0.95
Other patterns in variation
Leptodiaptomus sicilis is the most abundant species during
the winter. There was a large shift in the size of mature females
towards the end of December. These large and small individuals are the
same species (confirmed via COI sequencing), suggesting this shift may
reflect a transition from one generation to another and that, unlike in
many other lakes, there are two generations of L. sicilis per
year in Lake Champlain. This size difference may be caused by
differences in the developmental environments. For example, individuals
developing in January grow up at very low temperatures, and therefore
may reach larger sizes. These individuals oversummer in deep waters,
then re-emerge in October and produce a new generation. Water
temperatures are still fairly high through November, which results in a
generation of smaller individuals, which mature in time to produce a new
generation in January.
Shown below is the distribution of pairwise distances between COI
sequences of large and small morphs. Distances in both within- and
across-morph comparisons are small.
ind_dist = ape::dist.dna(sic_dnabin, model = "raw") %>% as.matrix %>%
as_tibble() %>%
mutate("ind1" = colnames(.)) %>%
pivot_longer(-ind1, names_to = "ind2", values_to = "dist") %>%
mutate(ind1 = factor(ind1),
ind2 = factor(ind2)) %>%
filter(!(ind1 == "sore1" | ind2 == "sore1")) %>%
mutate(
ind1 = case_when(
ind1 == "S1" ~ "small1",
ind1 == "S3" ~ "small3",
ind1 == "lsic3" ~ "small4",
ind1 == "lsic5" ~ "small6",
ind1 == "lsic9" ~ "small8",
ind1 == "lsic10" ~ "small9",
ind1 == "lsic11" ~ "small10",
ind1 == "L1" ~ "large1",
ind1 == "L2" ~ "large2",
ind1 == "L3" ~ "large3",
ind1 == "lsic1" ~ "large4",
ind1 == "lsic2" ~ "large5",
ind1 == "lsic7" ~ "large6",
ind1 == "lsic8" ~ "large7"),
ind2 = case_when(
ind2 == "S1" ~ "small1",
ind2 == "S3" ~ "small3",
ind2 == "lsic3" ~ "small4",
ind2 == "lsic5" ~ "small6",
ind2 == "lsic9" ~ "small8",
ind2 == "lsic10" ~ "small9",
ind2 == "lsic11" ~ "small10",
ind2 == "L1" ~ "large1",
ind2 == "L2" ~ "large2",
ind2 == "L3" ~ "large3",
ind2 == "lsic1" ~ "large4",
ind2 == "lsic2" ~ "large5",
ind2 == "lsic7" ~ "large6",
ind2 == "lsic8" ~ "large7"),
'comparison' = case_when(
str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "large") ~ "within",
str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "small") ~ "within",
str_detect(ind1, pattern = "large") & str_detect(ind2, pattern = "small") ~ "across",
str_detect(ind1, pattern = "small") & str_detect(ind2, pattern = "large") ~ "across"
))
ggplot(ind_dist, aes(dist, fill = comparison)) +
geom_histogram(binwidth = 0.005) +
labs(x = "Distance") +
theme_matt()

full_data %>%
filter(sp_name == "Leptodiaptomus sicilis") %>%
filter(sex != "juvenile") %>%
group_by(collection_date) %>%
mutate(size_center = scale(size, center = T, scale = F)) %>%
ggplot(aes(y = collection_date, x = size, fill = collection_temp)) +
facet_wrap(sex~.) +
geom_density_ridges(bandwidth = 0.04) +
geom_vline(xintercept = 0.89) +
labs(x = "Size (mm)",
y = "Date",
fill = "Coll. Temp. (°C)") +
theme_matt() +
theme(legend.position = "right",
axis.text.y = element_text(size = 12))

full_data %>%
filter(sp_name == "Leptodiaptomus minutus") %>%
filter(sex != "juvenile") %>%
ggplot(aes(y = collection_date, x = size, fill = collection_temp)) +
facet_wrap(sex~.) +
geom_density_ridges(bandwidth = 0.04) +
geom_vline(xintercept = 0.69) +
labs(x = "Size (mm)",
y = "Date",
fill = "Coll. Temp. (°C)") +
coord_cartesian(xlim = c(0.5,0.9)) +
theme_matt() +
theme(legend.position = "right",
axis.text.y = element_text(size = 12))

Distribution Lag Non-Linear Model (DLNM approach)
dlnm_data = full_data %>%
filter(sex == "female") %>%
select(collection_date, days_in_lab, collection_temp, replicate, sp_name, size, fecundity, ctmax) %>%
group_by(collection_date, collection_temp, sp_name) %>%
summarise(mean_ctmax = mean(ctmax, na.rm = T),
mean_size = mean(size, na.rm = T),
sample = n())
hourly_temps = raw_temps %>%
mutate(hour = lubridate::hour(dateTime)) %>%
group_by(date, hour) %>%
summarise(mean_temp = mean(degC)) %>%
ungroup() %>%
complete(date, nesting(hour)) %>%
mutate(timestep = ymd_hms(
paste(lubridate::as_date(date),
paste0(hour, ":00:00"), sep = " ")),
observation = row_number())
if(predict_vuln == F){
knitr::knit_exit()
}
LS0tCnRpdGxlOiBTZWFzb25hbGl0eSBpbiBMYWtlIENoYW1wbGFpbiBDb3BlcG9kIFRoZXJtYWwgTGltaXRzCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9VCwgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGLCBlY2hvID0gRn0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgZ2dwdWJyOjp0aGVtZV9wdWJyKGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGRhcmtfdGV4dCksCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gbWlkX3RleHQpLAogICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygzLCAwLCAwLCAwKSwgIm1tIikpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygwLCA1LCAwLCAwKSwgIm1tIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5nbGUgPSA5MCksCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9YmFzZV9zaXplICogMC45KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAwLjksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiksCiAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUsImNtIikKICAgICkKfQoKdGhlbWVfbWF0dF9mYWNldHMgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXJrX3RleHQgPSAiZ3JleTIwIil7CiAgbWlkX3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVsyXQogIGxpZ2h0X3RleHQgPC0gIG1vbm9jaHJvbWVSOjpnZW5lcmF0ZV9wYWxldHRlKGRhcmtfdGV4dCwgImdvX2xpZ2h0ZXIiLCBuX2NvbG91cnMgPSA1KVszXQogIAogIHRoZW1lX2J3KGJhc2VfZmFtaWx5PSJzYW5zIikgJStyZXBsYWNlJSAKICAgIHRoZW1lKAogICAgICBwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICBwYW5lbC5iYWNrZ3JvdW5kICA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksIAogICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLAogICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSBtaWRfdGV4dCwgbGluZWhlaWdodCA9IDEuMSksCiAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplKSwKICAgICAgdGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gZGFya190ZXh0KSwKICAgICAgYXhpcy50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBtaWRfdGV4dCksCiAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDMsIDAsIDAsIDApLCAibW0iKSksCiAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS4yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gdW5pdChjKDAsIDUsIDAsIDApLCAibW0iKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZSA9IDkwKSwKICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT1iYXNlX3NpemUgKiAwLjkpLAogICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDAuOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNlID0gImJvbGQiKSwKICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMC4yNSwgMC4yNSwgMC4yNSwgMC4yNSwiY20iKQogICAgKQp9CgpzcGVjaWVzX2NvbHMgPSBjKCJMZXB0b2RpYXB0b211cyBtaW51dHVzIiA9ICIjZmZkMDI5IiwKICAgICAgICAgICAgICAgICAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyBqdXZlbmlsZSIgPSAiI2UzZDhhZiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIG1pbnV0dXMgbWFsZSIgPSAiI2ZmZTg5NiIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiID0gIiNEODZGMjkiLAogICAgICAgICAgICAgICAgICJMZXB0b2RpYXB0b211cyBzaWNpbGlzIG1hbGUiID0gIiNFMjhDMDAiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMiID0gIiNDNUMzNUEiLAogICAgICAgICAgICAgICAgICJTa2lzdG9kaWFwdG9tdXMgb3JlZ29uZW5zaXMgbWFsZSIgPSAiI2U2ZTZhYSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIGp1dmVuaWxlIiA9ICJwbHVtMSIsIAogICAgICAgICAgICAgICAgICJFcGlzY2h1cmEgbGFjdXN0cmlzIG1hbGUiID0gInBsdW0zIiwgCiAgICAgICAgICAgICAgICAgIkVwaXNjaHVyYSBsYWN1c3RyaXMiID0gInBsdW00IiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyIgPSAic2t5Ymx1ZTQiLCAKICAgICAgICAgICAgICAgICAiTGltbm9jYWxhbnVzIG1hY3J1cnVzIG1hbGUiID0gInNreWJsdWUzIiwgCiAgICAgICAgICAgICAgICAgIkxpbW5vY2FsYW51cyBtYWNydXJ1cyBqdXZlbmlsZSIgPSAic2t5Ymx1ZSIsIAogICAgICAgICAgICAgICAgICJTZW5lY2VsbGEgY2FsYW5vaWRlcyIgPSAiZGFya3NlYWdyZWVuMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkgbWFsZSIgPSAibGlnaHRibHVlMyIsCiAgICAgICAgICAgICAgICAgIkxlcHRvZG9yYSBraW5kdGkiID0gImxpZ2h0Ymx1ZTQiLAogICAgICAgICAgICAgICAgICJMZXB0b2RvcmEga2luZHRpIGp1dmVuaWxlIiA9ICJsaWdodGJsdWUiLAogICAgICAgICAgICAgICAgICJPc3BocmFudGljdW0gbGFicm9uZWN0dW0iID0gImxpZ2h0Y29yYWwiKQpgYGAKCiMjIENvcGVwb2QgQ29sbGVjdGlvbgoKQ29wZXBvZHMgd2VyZSBjb2xsZWN0ZWQgYXQgYXBwcm94aW1hdGVseSB3ZWVrbHkgaW50ZXJ2YWxzIGZyb20gTGFrZSBDaGFtcGxhaW4gKEJ1cmxpbmd0b24gRmlzaGluZyBQaWVyKS4gUGxhbmt0b24gd2FzIGNvbGxlY3RlZCBmcm9tIHRoZSB0b3AgMyBtZXRlcnMgdXNpbmcgYSAyNTAgdW0gbWVzaCBuZXQuIAoKYGBge3J9CiMgTGFrZSBDaGFtcGxhaW4gbmVhciBCdXJsaW5ndG9uLCBWVApzaXRlTnVtYmVyID0gIjA0Mjk0NTAwIgpDaGFtcGxhaW5JbmZvID0gcmVhZE5XSVNzaXRlKHNpdGVOdW1iZXIpCnBhcmFtZXRlckNkID0gIjAwMDEwIgpzdGFydERhdGUgPSAiMjAyMy0wMS0wMSIKZW5kRGF0ZSA9ICIiCiNzdGF0Q2QgPSBjKCIwMDAwMSIsICIwMDAwMiIsIjAwMDAzIiwgIjAwMDExIikgIyAxIC0gbWF4LCAyIC0gbWluLCAzID0gbWVhbgoKIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBkYXRhIHdhbnRlZCB0aGVuIGRvd25sb2FkcyB0aGUgZGF0YQp1cmwgPSBjb25zdHJ1Y3ROV0lTVVJMKHNpdGVOdW1iZXJzID0gc2l0ZU51bWJlciwgcGFyYW1ldGVyQ2QgPSBwYXJhbWV0ZXJDZCwgCiAgICAgICAgICAgICAgICAgICAgICAgc3RhcnREYXRlID0gc3RhcnREYXRlLCBlbmREYXRlID0gZW5kRGF0ZSwgc2VydmljZSA9ICJ1diIpCgpyYXdfdGVtcHMgPSBpbXBvcnRXYXRlck1MMSh1cmwsIGFzRGF0ZVRpbWUgPSBUKSAlPiUgCiAgbXV0YXRlKCJkYXRlIiA9IGFzLkRhdGUoZGF0ZVRpbWUpKSAlPiUgCiAgc2VsZWN0KGRhdGVUaW1lLCB0el9jZCwgZGF0ZSwgZGVnQyA9IFhfMDAwMTBfMDAwMDApCgp0ZW1wX2RhdGEgPSAgcmF3X3RlbXBzICU+JSAKICBzZWxlY3QoZGF0ZSwgInRlbXAiID0gZGVnQykKYGBgCgpDb2xsZWN0aW9ucyBiZWdhbiBpbiBsYXRlIE1heSAyMDIzLiBTZXZlcmFsIGdhcHMgYXJlIHByZXNlbnQsIGJ1dCBjb2xsZWN0aW9ucyBoYXZlIGNvbnRpbnVlZCBhdCByb3VnaGx5IHdlZWtseSBpbnRlcnZhbHMgc2luY2UgdGhlbi4gQ29wZXBvZHMgZnJvbSBgciBsZW5ndGgodW5pcXVlKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX2RhdGUpKWAgY29sbGVjdGlvbnMgd2VyZSB1c2VkIHRvIG1ha2UgYSB0b3RhbCBvZiBgciBkaW0oZnVsbF9kYXRhKVsxXWAgdGhlcm1hbCBsaW1pdCBtZWFzdXJlbWVudHMuIE92ZXIgdGhpcyB0aW1lIHBlcmlvZCwgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgcmFuZ2VkIGZyb20gYHIgcGFzdGUobWluKGZ1bGxfZGF0YSRjb2xsZWN0aW9uX3RlbXApLCAiIHRvICIsIG1heChmdWxsX2RhdGEkY29sbGVjdGlvbl90ZW1wKSwgc2VwID0gIiIpYMKwQy4gICAgIAoKVGhlcmUgaXMgc3Vic3RhbnRpYWwgdmFyaWF0aW9uIGluIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGUgc3BlY2llcyBjb2xsZWN0ZWQuIFRoZXJlIGlzIGFsc28gc29tZSBkZWdyZWUgb2YgdmFyaWF0aW9uIHdpdGhpbiB0aGUgc3BlY2llcywgd2l0aCB0aGVybWFsIGxpbWl0cyBpbmNyZWFzaW5nIHNsaWdodGx5IGR1cmluZyB0aGUgc3VtbWVyLiAgICAKCmBgYHtyIGN0bWF4LXRpbWVzZXJpZXMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQojIyBEYWlseSB2YWx1ZXMgZm9yIHRoZSBwZXJpb2QgZXhhbWluZWQgYnkgZGF0YXNldApjb2xsZWN0aW9uX2NvbmRpdGlvbnMgPSB0ZW1wX2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoInJhbmdlX3RlbXAiID0gbWF4X3RlbXAgLSBtaW5fdGVtcCwKICAgICAgICAgZGF0ZSA9IGFzLkRhdGUoZGF0ZSkpICU+JSAKICB1bmdyb3VwKCkgJT4lICAKICBmaWx0ZXIoZGF0ZSA+PSAobWluKGFzLkRhdGUoZnVsbF9kYXRhJGNvbGxlY3Rpb25fZGF0ZSkpIC0gNykpCgojIyBNZWFuIGZlbWFsZSB0aGVybWFsIGxpbWl0cyBmb3IgZWFjaCBzcGVjaWVzLCBncm91cGVkIGJ5IGNvbGxlY3Rpb24Kc3BlY2llc19zdW1tYXJpZXMgPSBmdWxsX2RhdGEgJT4lICAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSwKICAgICAgICAgICAgImN0bWF4X3N0X2VyciIgPSAoc2QoY3RtYXgpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3N0X2VyciIgPSAoc2Qoc2l6ZSkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJzaXplX3ZhciIgPSB2YXIoc2l6ZSkpICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBhcnJhbmdlKGRlc2Moc2FtcGxlX3NpemUpKQoKYWR1bHRfc3VtbWFyaWVzID0gZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSwKICAgICAgICAgICAgImN0bWF4X3N0X2VyciIgPSAoc2QoY3RtYXgpIC8gc3FydChzYW1wbGVfc2l6ZSkpLAogICAgICAgICAgICAiY3RtYXhfdmFyIiA9IHZhcihjdG1heCksIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3N0X2VyciIgPSAoc2Qoc2l6ZSkgLyBzcXJ0KHNhbXBsZV9zaXplKSksCiAgICAgICAgICAgICJzaXplX3ZhciIgPSB2YXIoc2l6ZSkpICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBjb21wbGV0ZShzcF9uYW1lLCBjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBhcnJhbmdlKGRlc2Moc2FtcGxlX3NpemUpKQoKCmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICMgICAgICAgICAgICAgICAgICAgeW1pbiA9IG1lYW5fY3RtYXggLSBjdG1heF9zdF9lcnIsIHltYXggPSBtZWFuX2N0bWF4ICsgY3RtYXhfc3RfZXJyLAogICMgICAgICAgICAgICAgICAgICAgY29sb3VyID0gc3BfbmFtZSksCiAgIyAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwKICAjICAgICAgICAgICAgICAgd2lkdGggPSA1LCBsaW5ld2lkdGggPSAxKSArCiAgIyBnZW9tX3BvaW50KGRhdGEgPSBhZHVsdF9zdW1tYXJpZXMsIAogICMgICAgICAgICAgICBhZXMoeCA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSwgeSA9IG1lYW5fY3RtYXgsIGNvbG91ciA9IHNwX25hbWUsIHNpemUgPSBzYW1wbGVfc2l6ZSkpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZnVsbF9kYXRhLCAKICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpLAogICAgICAgICAgICAgc2l6ZSA9IDIsIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKHdpZHRoID0gMSwgaGVpZ2h0ID0gMCkpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRhdGUiLCAKICAgICAgIHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIiwKICAgICAgIHNpemUgPSAiU2FtcGxlIFNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKU2l6ZSBhbHNvIHZhcmllZCwgYnV0IHByaW1hcmlseSBiZXR3ZWVuIHJhdGhlciB0aGFuIHdpdGhpbiBzcGVjaWVzLiAKCmBgYHtyIHNpemUtdGltZXNlcmllcywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTV9CmdncGxvdCgpICsgCiAgZ2VvbV92bGluZShkYXRhID0gdW5pcXVlKHNlbGVjdChmdWxsX2RhdGEsIGNvbGxlY3Rpb25fZGF0ZSkpLCAKICAgICAgICAgICAgIGFlcyh4aW50ZXJjZXB0ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpKSwKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5OTAiLAogICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGNvbGxlY3Rpb25fY29uZGl0aW9ucywgCiAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShkYXRlKSwgeSA9IG1lYW5fdGVtcCksCiAgICAgICAgICAgIGNvbG91ciA9ICJibGFjayIsIAogICAgICAgICAgICBsaW5ld2lkdGggPSAyKSArIAogICMgZ2VvbV9lcnJvcmJhcihkYXRhID0gc3BlY2llc19zdW1tYXJpZXMsCiAgIyAgICAgICAgICAgICAgIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCAKICAjICAgICAgICAgICAgICAgICAgIHltaW4gPSBtZWFuX2N0bWF4IC0gY3RtYXhfc3RfZXJyLCB5bWF4ID0gbWVhbl9jdG1heCArIGN0bWF4X3N0X2VyciwKICAjICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IHNwX25hbWUpLAogICMgICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMSksCiAgIyAgICAgICAgICAgICAgIHdpZHRoID0gNSwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBhZHVsdF9zdW1tYXJpZXMsIAogICAgICAgICAgICAgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBtZWFuX3NpemUgKiA0MCwgY29sb3VyID0gc3BfbmFtZSwgc2l6ZSA9IHNhbXBsZV9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMoCiAgICBuYW1lID0gIlRlbXBlcmF0dXJlIiwgIyBGZWF0dXJlcyBvZiB0aGUgZmlyc3QgYXhpcwogICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+Li80MCwgbmFtZT0iUHJvc29tZSBMZW5ndGggKG1tKSIpLCAjIEFkZCBhIHNlY29uZCBheGlzIGFuZCBzcGVjaWZ5IGl0cyBmZWF0dXJlcwogICAgYnJlYWtzID0gYygwLDUsMTAsMTUsMjAsMjUsMzApCiAgKSArIAogIGxhYnMoeCA9ICJEYXRlIiwgCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpTaG93biBiZWxvdyBpcyBDVG1heCBhbmQgYm9keSBzaXplIGZvciB0aGUgc3BlY2llcyB3aXRoIHRoZSBtb3N0IGRhdGEgKCpTa2lzdG9kaWFwdG9tdXMqLCAqTC4gbWludXR1cyosICpMLiBzaWNpbGlzKiwgYW5kICpFcGlzY2h1cmEqKSwgcGxvdHRlZCBhZ2FpbnN0IHRoZSBkYXkgb2YgdGhlIHllYXIgZm9yIGVhY2ggc2V4L3N0YWdlIHNlcGFyYXRlbHkuIAoKYGBge3IgdHJhaXQtZG95LWZlYXR1cmUsIGZpZy53aWR0aCA9IDE0LCBmaWcuaGVpZ2h0ID0gN30KY3RtYXhfZmVhdHVyZSA9IGZ1bGxfZGF0YSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGMoIlNraXN0b2RpYXB0b211cyBvcmVnb25lbnNpcyIsICJMZXB0b2RpYXB0b211cyBtaW51dHVzIiwgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiLCAiRXBpc2NodXJhIGxhY3VzdHJpcyIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X2dyaWQoc3BfbmFtZX5zZXgpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkRheSBvZiB0aGUgWWVhciIsIAogICAgICAgeSA9ICJDVG1heCAowrBDKSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCnNpemVfZmVhdHVyZSA9IGZ1bGxfZGF0YSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICBmaWx0ZXIoc3BfbmFtZSAlaW4lIGMoIlNraXN0b2RpYXB0b211cyBvcmVnb25lbnNpcyIsICJMZXB0b2RpYXB0b211cyBtaW51dHVzIiwgIkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMiLCAiRXBpc2NodXJhIGxhY3VzdHJpcyIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gc2l6ZSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfZ3JpZChzcF9uYW1lfnNleCkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiRGF5IG9mIHRoZSBZZWFyIiwgCiAgICAgICB5ID0gIlNpemUgKG1tKSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMDAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpLAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKCmdnYXJyYW5nZShjdG1heF9mZWF0dXJlLCBzaXplX2ZlYXR1cmUsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAibm9uZSIpCmBgYAoKYGBge3Igc3AtcHJvcHMsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNX0KYWR1bHRfc3VtbWFyaWVzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZShjb2xsZWN0aW9uX251bSA9IGFzLm51bWVyaWMoZmFjdG9yKGNvbGxlY3Rpb25fZGF0ZSkpKSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlKSAlPiUgIAogIGFycmFuZ2UoY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgc2VsZWN0KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl9udW0sIHNhbXBsZV9zaXplKSAlPiUgCiAgbXV0YXRlKHNhbXBsZV9zaXplID0gcmVwbGFjZV9uYShzYW1wbGVfc2l6ZSwgMCkpICU+JSAKICBtdXRhdGUodG90YWwgPSBzdW0oc2FtcGxlX3NpemUpLAogICAgICAgICBwZXJjZW50YWdlID0gc2FtcGxlX3NpemUgLyB0b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX2RhdGUsIHkgPSBwZXJjZW50YWdlLCBmaWxsID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9hcmVhKCkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWluaW1hbChiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGlja3MgPSBlbGVtZW50X2xpbmUoKSkKYGBgCgoKYGBge3Igb3RoZXItcHJvcHN9CnBhdGhvZ2VuX2NvbHMgPSBjKCJubyIgPSAiZ3JleTk1IiwgImNsb3VkeSIgPSAiaG9uZXlkZXczIiwgInNwb3QiID0gImFudGlxdWV3aGl0ZTMiLCAib3RoZXIiID0gInRvbWF0bzMiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoKSAlPiUgCiAgZmlsdGVyKHNleCAhPSAianV2ZW5pbGUiKSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlKSAlPiUgCiAgY291bnQocGF0aG9nZW4pICU+JSAKICBmaWx0ZXIocGF0aG9nZW4gIT0gInVuY2VydGFpbiIpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gImNvbGxlY3Rpb25fZGF0ZSIsIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBwYXRob2dlbiwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgY2xvdWR5LCBzcG90LCBvdGhlcikpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobm8sIGNsb3VkeSwgc3BvdCwgb3RoZXIpLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJwYXRob2dlbiIsIAogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC90b3RhbCwKICAgICAgICAgY29sbGVjdGlvbl9kYXRlID0gbHVicmlkYXRlOjphc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSksCiAgICAgICAgIHBhdGhvZ2VuID0gZmN0X3JlbGV2ZWwocGF0aG9nZW4sICJubyIsICJjbG91ZHkiLCAic3BvdCIsICJvdGhlciIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gY29sbGVjdGlvbl9kYXRlLCB5ID0gcGVyY2VudCwgZmlsbCA9IHBhdGhvZ2VuKSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHBhdGhvZ2VuX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiUGF0aG9nZW4iKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCgpkZXZfZWdnc19jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJ5ZXMiID0gImxpZ2h0Ymx1ZTMiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KGRldl9lZ2dzKSAlPiUgCiAgZmlsdGVyKGRldl9lZ2dzICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoImNvbGxlY3Rpb25fZGF0ZSIsICJzcF9uYW1lIiksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBkZXZfZWdncywgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgeWVzKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhubywgeWVzKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiZGV2X2VnZ3MiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvdW50IikgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gY291bnQvdG90YWwsCiAgICAgICAgIGNvbGxlY3Rpb25fZGF0ZSA9IGx1YnJpZGF0ZTo6YXNfZGF0ZShjb2xsZWN0aW9uX2RhdGUpLAogICAgICAgICBkZXZfZWdncyA9IGZjdF9yZWxldmVsKGRldl9lZ2dzLCAibm8iLCAieWVzIikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKGNvbGxlY3Rpb25fZGF0ZSwgbmVzdGluZyhzcF9uYW1lLCBkZXZfZWdncyksIGZpbGwgPSBsaXN0KHBlcmNlbnQgPSAxKSkgJT4lIAogIG11dGF0ZShwZXJjZW50ID0gaWZfZWxzZShpcy5uYSh0b3RhbCkgJiBkZXZfZWdncyA9PSAieWVzIiwgMCwgcGVyY2VudCkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX2RhdGUsIHkgPSBwZXJjZW50LCBmaWxsID0gZGV2X2VnZ3MpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGRldl9lZ2dzX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiRGV2ZWxvcGluZyBcbkVnZ3MiKSArIAogIHRoZW1lX21pbmltYWwoYmFzZV9zaXplID0gMjApICsgCiAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzID0gZWxlbWVudF9saW5lKCkpCgpsaXBpZF9jb2xzID0gYygibm8iID0gImdyZXk5NSIsICJ5ZXMiID0gInNpZW5uYTIiKQoKZnVsbF9kYXRhICU+JSAKICBzZWxlY3QoY29sbGVjdGlvbl9kYXRlLCBkZXZfZWdncywgcGF0aG9nZW4sIGxpcGlkcywgc3BfbmFtZSwgc2V4KSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSkgJT4lIAogIGNvdW50KGxpcGlkcykgJT4lIAogIGZpbHRlcihsaXBpZHMgIT0gInVuY2VydGFpbiIpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYygiY29sbGVjdGlvbl9kYXRlIiwgInNwX25hbWUiKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IGxpcGlkcywgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBuLAogICAgICAgICAgICAgIHZhbHVlc19maWxsID0gMCkgJT4lIAogIG11dGF0ZSh0b3RhbCA9IHN1bShubywgeWVzKSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhubywgeWVzKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAibGlwaWRzIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjb3VudCIpICU+JSAKICBtdXRhdGUocGVyY2VudCA9IGNvdW50L3RvdGFsLAogICAgICAgICBjb2xsZWN0aW9uX2RhdGUgPSBsdWJyaWRhdGU6OmFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSwKICAgICAgICAgbGlwaWRzID0gZmN0X3JlbGV2ZWwobGlwaWRzLCAibm8iLCAieWVzIikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKGNvbGxlY3Rpb25fZGF0ZSwgbmVzdGluZyhzcF9uYW1lLCBsaXBpZHMpLCBmaWxsID0gbGlzdChwZXJjZW50ID0gMSkpICU+JSAKICBtdXRhdGUocGVyY2VudCA9IGlmX2Vsc2UoaXMubmEodG90YWwpICYgbGlwaWRzID09ICJ5ZXMiLCAwLCBwZXJjZW50KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fZGF0ZSwgeSA9IHBlcmNlbnQsIGZpbGwgPSBsaXBpZHMpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBuY29sID0gMSkgKyAKICBnZW9tX2FyZWEoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGxpcGlkX2NvbHMpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwxKSkgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBEYXRlIiwgCiAgICAgICB5ID0gIlByb3BvcnRpb24iLCAKICAgICAgIGZpbGwgPSAiTGlwaWRzXG5QcmVzZW50IikgKyAKICB0aGVtZV9taW5pbWFsKGJhc2Vfc2l6ZSA9IDIwKSArIAogIHRoZW1lKHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfbGluZSgpKQpgYGAKCgojIyBUZW1wZXJhdHVyZSBWYXJpYWJpbGl0eQpMYWtlIENoYW1wbGFpbiBpcyBoaWdobHkgc2Vhc29uYWwsIHdpdGggYm90aCBhdmVyYWdlIHRlbXBlcmF0dXJlcyBhbmQgdGVtcGVyYXR1cmUgdmFyaWFiaWxpdHkgY2hhbmdpbmcgdGhyb3VnaG91dCB0aGUgeWVhci4gVGhlc2UgcGF0dGVybnMgaW4gdGhlIGV4cGVyaWVuY2VkIHRoZXJtYWwgZW52aXJvbm1lbnQgbWF5IGRyaXZlIHRoZSBvYnNlcnZlZCB2YXJpYXRpb24gaW4gY29wZXBvZCB0aGVybWFsIGxpbWl0cy4gSG93ZXZlciwgdGhlIHRpbWUgcGVyaW9kIGFmZmVjdGluZyBjb3BlcG9kIHRoZXJtYWwgbGltaXRzIGlzIHVua25vd24uIERlcGVuZGluZyB0aGUgb24gdGhlIGR1cmF0aW9uIG9mIHRpbWUgY29uc2lkZXJlZCwgdGhlcmUgYXJlIGxhcmdlIGNoYW5nZXMgaW4gdGhlIGV4cGVyaWVuY2VkIGVudmlyb25tZW50LCBpbiBwYXJ0aWN1bGFyIHJlZ2FyZGluZyB0aGUgdGVtcGVyYXR1cmUgcmFuZ2UgYW5kIHZhcmlhbmNlLiBDb25zaWRlciBmb3IgZXhhbXBsZSB0aHJlZSB0aW1lIHBlcmlvZHM6IHRoZSBkYXkgb2YgY29sbGVjdGlvbiwgb25lIHdlZWsgcHJpb3IgdG8gY29sbGVjdGlvbiwgYW5kIGZvdXIgd2Vla3MgcHJpb3IgdG8gY29sbGVjdGlvbi4gV2hpbGUgdGhlIG92ZXJhbGwgcGF0dGVybiBpcyBzaW1pbGFyLCB3ZSBjYW4gc2VlIHRoYXQsIHVuc3VycHJpc2luZ2x5LCBjb25zaWRlcmluZyBsb25nZXIgcGVyaW9kcyBvZiB0aW1lIHJlc3VsdHMgaW4gbGFyZ2VyIHJhbmdlcyBhbmQgc2xpZ2h0bHkgY2hhbmdlcyB0aGUgcGF0dGVybiBvZiB2YXJpYW5jZSBleHBlcmllbmNlZC4gCgpgYGB7ciBkYWlseS10ZW1wLWRhdGF9CiMjIERhaWx5IHZhbHVlcwpkYWlseV90ZW1wX2RhdGEgPSB0ZW1wX2RhdGEgJT4lCiAgdW5ncm91cCgpICU+JSAKICBncm91cF9ieShkYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4odGVtcCksCiAgICAgICAgICAgIG1lZF90ZW1wID0gbWVkaWFuKHRlbXApLAogICAgICAgICAgICB2YXJfdGVtcCA9IHZhcih0ZW1wKSwgCiAgICAgICAgICAgIG1pbl90ZW1wID0gbWluKHRlbXApLCAKICAgICAgICAgICAgbWF4X3RlbXAgPSBtYXgodGVtcCkpICU+JSAKICBtdXRhdGUoInJhbmdlX3RlbXAiID0gbWF4X3RlbXAgLSBtaW5fdGVtcCkKCmRheV9wcmlvcl90ZW1wX2RhdGEgPSB0ZW1wX2RhdGEgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtZWRfdGVtcCA9IG1lZGlhbih0ZW1wKSwKICAgICAgICAgICAgdmFyX3RlbXAgPSB2YXIodGVtcCksIAogICAgICAgICAgICBtaW5fdGVtcCA9IG1pbih0ZW1wKSwgCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXApKSAlPiUgCiAgbXV0YXRlKGRhdGUgPSBkYXRlICsgMSkgJT4lIAogIHJlbmFtZV93aXRoKC5mbiA9IH4gcGFzdGUwKCJwcmlvcl9kYXlfIiwgLngpLCAuY29scyA9IGMoLWRhdGUpKQoKZGFpbHlfcGxvdCA9IGRhaWx5X3RlbXBfZGF0YSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ0ZW1wIikgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wLCBjb2xvdXIgPSBwYXJhbWV0ZXIpKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygKICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAogICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAogICAgIm1heF90ZW1wIiA9ICJ0b21hdG8iLCAgCiAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAogICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAogICAgInZhcl90ZW1wIiA9ICJkYXJrZ29sZGVucm9kMSIKICApKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArIAogIGdndGl0bGUoIkRhaWx5IFZhbHVlcyIpICsgCiAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKICAgICAgIHggPSAiIikgKyAKICB0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkgKyAKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKYGBgCgpgYGB7ciBwcmVkaWN0b3JzLWZ1bmN0aW9ufQojIyBEZWZpbmluZyB0aGUgZnVuY3Rpb24gdG8gZ2V0IHByZWRpY3RvciB2YWx1ZXMgZm9yIHBlcmlvZHMgb2YgZGlmZmVyZW50IGxlbmd0aHMKZ2V0X3ByZWRpY3RvcnMgPSBmdW5jdGlvbihkYWlseV92YWx1ZXMsIHJhd190ZW1wLCBuX2RheXMpewogIHByZWZpeCA9IHN0cl9yZXBsYWNlX2FsbCh4ZnVuOjpudW1iZXJzX3RvX3dvcmRzKG5fZGF5cyksIHBhdHRlcm4gPSAiICIsIHJlcGxhY2VtZW50ID0gIi0iKQogIAogIG1lYW5fdmFsdWVzID0gZGFpbHlfdmFsdWVzICU+JSAKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBtdXRhdGUobWVhbl9tYXggPSBzbGlkZV92ZWMoLnggPSBtYXhfdGVtcCwgLmYgPSBtZWFuLCAuYmVmb3JlID0gbl9kYXlzLCAuY29tcGxldGUgPSBUKSwKICAgICAgICAgICBtZWFuX21pbiA9IHNsaWRlX3ZlYygueCA9IG1pbl90ZW1wLCAuZiA9IG1lYW4sIC5iZWZvcmUgPSBuX2RheXMsIC5jb21wbGV0ZSA9IFQpLAogICAgICAgICAgIG1lYW5fcmFuZ2UgPSBzbGlkZV92ZWMoLnggPSByYW5nZV90ZW1wLCAuZiA9IG1lYW4sIC5iZWZvcmUgPSBuX2RheXMsIC5jb21wbGV0ZSA9IFQpKSAlPiUgCiAgICBzZWxlY3QoZGF0ZSwgbWVhbl9tYXgsIG1lYW5fbWluLCBtZWFuX3JhbmdlKSAlPiUgCiAgICByZW5hbWVfd2l0aCggfiBwYXN0ZShwcmVmaXgsICJkYXkiLCAueCwgc2VwID0gIl8iKSwgLmNvbHMgPSBjKC1kYXRlKSkKICAKICBwZXJpb2RfdmFsdWVzID0gcmF3X3RlbXAgJT4lIAogICAgbXV0YXRlKG1lYW4gPSBzbGlkZV9pbmRleF9tZWFuKHRlbXAsIGkgPSBkYXRlLCBiZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hX3JtID0gVCksCiAgICAgICAgICAgbWF4ID0gc2xpZGVfaW5kZXhfbWF4KHRlbXAsIGkgPSBkYXRlLCBiZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYV9ybSA9IFQpLAogICAgICAgICAgIG1pbiA9IHNsaWRlX2luZGV4X21pbih0ZW1wLCBpID0gZGF0ZSwgYmVmb3JlID0gZGF5cyhuX2RheXMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYV9ybSA9IFQpLAogICAgICAgICAgIG1lZCA9IHNsaWRlX2luZGV4X2RibCh0ZW1wLCAuaSA9IGRhdGUsIC5iZWZvcmUgPSBkYXlzKG5fZGF5cyksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYV9ybSA9IFQsIC5mID0gbWVkaWFuKSwKICAgICAgICAgICB2YXIgPSBzbGlkZV9pbmRleF9kYmwodGVtcCwgLmkgPSBkYXRlLCAuYmVmb3JlID0gZGF5cyhuX2RheXMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmYgPSB2YXIpLAogICAgICAgICAgIHJhbmdlID0gbWF4IC0gbWluKSAlPiUgIAogICAgc2VsZWN0KC10ZW1wKSAlPiUgIAogICAgZGlzdGluY3QoKSAlPiUgCiAgICByZW5hbWVfd2l0aCggfiBwYXN0ZShwcmVmaXgsICJkYXkiLCAueCwgc2VwID0gIl8iKSwgLmNvbHMgPSBjKC1kYXRlKSklPiUgCiAgICBpbm5lcl9qb2luKG1lYW5fdmFsdWVzLCBieSA9IGMoImRhdGUiKSkgJT4lICAKICAgIGRyb3BfbmEoKQogIAogIHJldHVybihwZXJpb2RfdmFsdWVzKQp9CmBgYAoKYGBge3IgcHJlZGljdG9ycy1hbmQtcGxvdHMsIGZpZy53aWR0aD0xMiwgZmlnLmhlaWdodD01fQojICMjIEdldHRpbmcgcHJlZGljdG9yIHZhcmlhYmxlcyBmb3IgZGlmZmVyZW50IHBlcmlvZHMKIyAKIyAjIyMgU2hvcnQgKHRocmVlIGRheXMpCiMgdGhyZWVfZGF5X3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXdfdGVtcCA9IHRlbXBfZGF0YSwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gMykKIyAKIyAjIyMgT05FIFdFRUsKd2Vla190ZW1wcyA9IGdldF9wcmVkaWN0b3JzKGRhaWx5X3ZhbHVlcyA9IGRhaWx5X3RlbXBfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gNykKCndlZWtfcGxvdCA9IHdlZWtfdGVtcHMgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKC1kYXRlKSwKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUKICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygic2V2ZW5fZGF5X21lYW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfbWVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X21heCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNldmVuX2RheV9taW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzZXZlbl9kYXlfdmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2V2ZW5fZGF5X3JhbmdlIikpICU+JQogIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKwogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIm1lYW5fdGVtcCIgPSAib2xpdmVkcmFiMyIsCiAgICAibWVkX3RlbXAiID0gInNlYWdyZWVuMyIsCiAgICAibWF4X3RlbXAiID0gInRvbWF0byIsCiAgICAibWluX3RlbXAiID0gImRvZGdlcmJsdWUiLAogICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAogICAgInZhcl90ZW1wIiA9ICJkYXJrZ29sZGVucm9kMSIKICApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGFzLkRhdGUoYygiMjAyMy0wMS0wMSIsICIyMDIzLTA0LTAxIiwgIjIwMjMtMDctMDEiKSkpICsKICBnZ3RpdGxlKCJPbmUgV2VlayIpICsKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKIyAKIyAKIyAjIyMgVFdPIFdFRUtTCiMgdHdvX3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gMTQpCiMgCiMgdHdvX3dlZWtfcGxvdCA9IHR3b193ZWVrX3RlbXBzICU+JSAKIyAgIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiMgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiMgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiMgICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygiZm91cnRlZW5fZGF5X21lYW4iLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9tZWQiLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvdXJ0ZWVuX2RheV9tYXgiLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3VydGVlbl9kYXlfbWluIiwgCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X3ZhciIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZm91cnRlZW5fZGF5X3JhbmdlIikpICU+JSAKIyAgIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAojICAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKIyAgICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAojICAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKIyAgICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKIyAgICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAojICAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgojICAgKSkgKyAKIyAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArIAojICAgZ2d0aXRsZSgiVHdvIFdlZWtzIikgKyAKIyAgIGxhYnMoeSA9ICJUZW1wZXJhdHVyZSAowrBDKSIsCiMgICAgICAgIHggPSAiIikgKyAKIyAgIHRoZW1lX2J3KGJhc2Vfc2l6ZSA9IDIwKSArIAojICAgdGhlbWUocGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKIyAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKIyAKIyAKIyAjIyMgRk9VUiBXRUVLUwpmb3VyX3dlZWtfdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gdGVtcF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSAyOCkKCmZvdXJfd2Vla19wbG90ID0gZm91cl93ZWVrX3RlbXBzICU+JQogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInBhcmFtZXRlciIsCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ0ZW1wIikgJT4lCiAgZmlsdGVyKHBhcmFtZXRlciAlaW4lIGMoInR3ZW50eS1laWdodF9kYXlfbWVhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfbWVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9tYXgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ0d2VudHktZWlnaHRfZGF5X21pbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInR3ZW50eS1laWdodF9kYXlfdmFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAidHdlbnR5LWVpZ2h0X2RheV9yYW5nZSIpKSAlPiUKICBtdXRhdGUocGFyYW1ldGVyID0gcGFzdGUod29yZChwYXJhbWV0ZXIsIHN0YXJ0ID0gMywgc2VwID0gZml4ZWQoIl8iKSksICJfdGVtcCIsIHNlcCA9ICIiKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZGF0ZSwgeSA9IHRlbXAsIGNvbG91ciA9IHBhcmFtZXRlcikpICsKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMSkgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygKICAgICJtZWFuX3RlbXAiID0gIm9saXZlZHJhYjMiLAogICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAogICAgIm1heF90ZW1wIiA9ICJ0b21hdG8iLAogICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKICAgICJyYW5nZV90ZW1wIiA9ICJnb2xkZW5yb2QzIiwKICAgICJ2YXJfdGVtcCIgPSAiZGFya2dvbGRlbnJvZDEiCiAgKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArCiAgZ2d0aXRsZSgiRm91ciBXZWVrcyIpICsKICBsYWJzKHkgPSAiVGVtcGVyYXR1cmUgKMKwQykiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsKICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMjcwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKIyAKIyAKIyAjIyMgRUlHSFQgV0VFS1MKIyBlaWdodF93ZWVrX3RlbXBzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gZGFpbHlfdGVtcF9kYXRhLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2RheXMgPSA1NikKIyAKIyBlaWdodF93ZWVrX3Bsb3QgPSBlaWdodF93ZWVrX3RlbXBzICU+JSAKIyAgIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSksCiMgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicGFyYW1ldGVyIiwgCiMgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInRlbXAiKSAlPiUgCiMgICBmaWx0ZXIocGFyYW1ldGVyICVpbiUgYygiZmlmdHktc2l4X2RheV9tZWFuIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21lZCIsCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlmdHktc2l4X2RheV9tYXgiLCAKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X21pbiIsIAojICAgICAgICAgICAgICAgICAgICAgICAgICAgImZpZnR5LXNpeF9kYXlfdmFyIiwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmaWZ0eS1zaXhfZGF5X3JhbmdlIikpICU+JSAKIyAgIG11dGF0ZShwYXJhbWV0ZXIgPSBwYXN0ZSh3b3JkKHBhcmFtZXRlciwgc3RhcnQgPSAzLCBzZXAgPSBmaXhlZCgiXyIpKSwgIl90ZW1wIiwgc2VwID0gIiIpKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gdGVtcCwgY29sb3VyID0gcGFyYW1ldGVyKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKAojICAgICAibWVhbl90ZW1wIiA9ICJvbGl2ZWRyYWIzIiwKIyAgICAgIm1lZF90ZW1wIiA9ICJzZWFncmVlbjMiLAojICAgICAibWF4X3RlbXAiID0gInRvbWF0byIsICAKIyAgICAgIm1pbl90ZW1wIiA9ICJkb2RnZXJibHVlIiwKIyAgICAgInJhbmdlX3RlbXAiID0gImdvbGRlbnJvZDMiLAojICAgICAidmFyX3RlbXAiID0gImRhcmtnb2xkZW5yb2QxIgojICAgKSkgKyAKIyAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBhcy5EYXRlKGMoIjIwMjMtMDEtMDEiLCAiMjAyMy0wNC0wMSIsICIyMDIzLTA3LTAxIikpKSArIAojICAgZ2d0aXRsZSgiRWlnaHQgV2Vla3MiKSArIAojICAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKIyAgICAgICAgeCA9ICIiKSArIAojICAgdGhlbWVfYncoYmFzZV9zaXplID0gMjApICsgCiMgICB0aGVtZShwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAyNzAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQojIApnZ2FycmFuZ2UoZGFpbHlfcGxvdCwgd2Vla19wbG90LCBmb3VyX3dlZWtfcGxvdCwgCiAgICAgICAgICBjb21tb24ubGVnZW5kID0gVCwgbnJvdyA9IDEsIGxlZ2VuZCA9ICJib3R0b20iKQpgYGAKClRoZSBkaWZmZXJlbnQgdGltZSBwZXJpb2RzIGV4YW1pbmVkIGJ5IHRoaXMgY2xpbWF0ZSBkYXRhIGhpZ2hsaWdodHMgdGhhdCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWluaW11bSBhbmQgbWF4aW11bSB0ZW1wZXJhdHVyZXMgY2hhbmdlcyBiYXNlZCBvbiB0aGUgd2luZG93IGV4YW1pbmVkLiBGb3IgZXhhbXBsZSwgbWluaW11bSBhbmQgbWF4aW11bSB0ZW1wZXJhdHVyZXMgZXhwZXJpZW5jZWQgb3ZlciB3ZWVrbHkgaW50ZXJ2YWxzIGFyZSBjbG9zZWx5IGxpbmtlZCwgd2hlcmVhcyB0aGVyZSBpcyBhIGRpc3RpbmN0IHNlYXNvbmFsIGN5Y2xlIGluIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBtaW5pbXVtIGFuZCBtYXhpbXVtIHRlbXBlcmF0dXJlcyBleHBlcmllbmNlZCBvdmVyIHBlcmlvZHMgb2YgZm91ciB3ZWVrcy4gCgpgYGB7cn0Kb25lX3dlZWtfZG95X2RhdGEgPSB3ZWVrX3RlbXBzICU+JSAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSkKCm9uZV93ZWVrX3RlbXBfY2lyY2xlID0gZ2dwbG90KG9uZV93ZWVrX2RveV9kYXRhLCBhZXMoeCA9IHNldmVuX2RheV9tZWFuX21heCwgeSA9IHNldmVuX2RheV9tZWFuX21pbiwgY29sb3VyID0gZG95KSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKAogICAgaGlnaCA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWQgPSAiY29yYWwyIiwKICAgIGxvdyA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWRwb2ludCA9IDE4Mi41KSArIAogIGxhYnMoeCA9ICJNYXguIFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWluLiBUZW1wLiAowrBDKSIpICsgCiAgbGFicyh4ID0gIk1heC4gVGVtcC4gKMKwQykiLAogICAgICAgeSA9ICJNaW4uIFRlbXAuICjCsEMpIikgKyAKICBnZ3RpdGxlKCJPbmUgV2VlayIpICsgCiAgdGhlbWVfbWF0dCgpCgpmb3VyX3dlZWtfZG95X2RhdGEgPSBmb3VyX3dlZWtfdGVtcHMgJT4lIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpKQoKZm91cl93ZWVrX3RlbXBfY2lyY2xlID0gZ2dwbG90KGZvdXJfd2Vla19kb3lfZGF0YSwgYWVzKHggPSBgdHdlbnR5LWVpZ2h0X2RheV9tYXhgLCB5ID0gYHR3ZW50eS1laWdodF9kYXlfbWluYCwgY29sb3VyID0gZG95KSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKAogICAgaGlnaCA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWQgPSAiY29yYWwyIiwKICAgIGxvdyA9ICJkb2RnZXJibHVlNCIsCiAgICBtaWRwb2ludCA9IDE4Mi41KSArIAogIGxhYnMoeCA9ICJNYXguIFRlbXAuICjCsEMpIiwKICAgICAgIHkgPSAiTWluLiBUZW1wLiAowrBDKSIpICsgCiAgZ2d0aXRsZSgiRm91ciBXZWVrIikgKyAKICB0aGVtZV9tYXR0KCkKCmdnYXJyYW5nZShvbmVfd2Vla190ZW1wX2NpcmNsZSwgZm91cl93ZWVrX3RlbXBfY2lyY2xlLAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJib3R0b20iKQpgYGAKClRoZSB0aGVybWFsIGVudmlyb25tZW50IG92ZXIgYW55IHBlcmlvZCBvZiB0aW1lIG1heSBkcml2ZSBwYXR0ZXJucyBpbiB0aGVybWFsIGFjY2xpbWF0aW9uLiBUbyBleHBsb3JlIHRoZSBwb3RlbnRpYWwgZWZmZWN0cyBvZiBkaWZmZXJlbnQgYWNjbGltYXRpb24gd2luZG93cywgd2UgZXhhbWluZWQgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhlcm1hbCBsaW1pdHMgYW5kIGRpZmZlcmVudCByZXByZXNlbnRhdGlvbnMgb2YgdGhlIHRoZXJtYWwgZW52aXJvbm1lbnQgZm9yIGRpZmZlcmVudCBwZXJpb2RzIG9mIHRpbWUuIFNob3duIGJlbG93IGFyZSB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnRzIGZvciB0aGVzZSByZWxhdGlvbnNoaXBzLiBFYWNoIGZhY2V0IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgZm9yIGEgZGlmZmVyZW50IGRpbWVuc2lvbiBvZiB0aGUgdGhlcm1hbCBlbnZpcm9ubWVudC4gQ29ycmVsYXRpb24gY29lZmZpY2llbnRzIGFyZSBwbG90dGVkIGZvciBkaWZmZXJlbnQgZHVyYXRpb25zLCBmb3Igc3BlY2llcyB0aGF0IHdlcmUgY29sbGVjdGVkIG1vcmUgdGhhbiBmaXZlIHRpbWVzLiBPbmx5IGRhdGEgZm9yIG1hdHVyZSBmZW1hbGUgY29wZXBvZHMgd2FzIGluY2x1ZGVkLiAKCldlIGNhbiBzZWUgdGhhdCwgaW4gZ2VuZXJhbCwgY29wZXBvZHMgYXJlIHJlc3BvbmRpbmcgdG8gcHJveGltYXRlIGN1ZXMgZnJvbSB0aGUgdGhlcm1hbCBlbnZpcm9ubWVudCwgd2l0aCBjb3JyZWxhdGlvbnMgZ2VuZXJhbGx5IGRyb3BwaW5nIG9mZiBzdWJzdGFudGlhbGx5IGFzIGFjY2xpbWF0aW9uIHdpbmRvdyBkdXJhdGlvbiBpbmNyZWFzZXMuIEFuIGV4Y2VwdGlvbiBpcyAqRXBpc2NodXJhIGxhY3VzdHJpcyosIHdoaWNoIGFwcGVhcnMgdG8gYmUgcmVzcG9uZGluZyB0byBtYXhpbXVtIHRlbXBlcmF0dXJlcyBleHBlcmllbmNlZCBvdmVyIGEgMjAgZGF5IHRpbWUgcGVyaW9kLiAKCmBgYHtyfQojIyMgUHVsbGluZyBwcmVkaWN0b3JzIGFuZCBtZWFzdXJpbmcgY29ycmVsYXRpb25zIGZvciBtdWNoIGZpbmVyIHRpbWVzY2FsZXM7IDEtNTYgZGF5cwoKbnVtX2NvbGxzID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgc3BfbmFtZSkgJT4lICAKICBkaXN0aW5jdCgpICU+JSAgCiAgY291bnQoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihuID49IDUpCgpjb3JyX3ZhbHMgPSBkYXRhLmZyYW1lKCkKCmR1cl92YWxzID0gYygxOjUwKQpmb3IoaSBpbiBkdXJfdmFscyl7CiAgCiAgZHVyYXRpb25fdGVtcHMgPSBnZXRfcHJlZGljdG9ycyhkYWlseV92YWx1ZXMgPSBkYWlseV90ZW1wX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3X3RlbXAgPSB0ZW1wX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9kYXlzID0gaSkgJT4lIAogICAgZmlsdGVyKGRhdGUgJWluJSBhc19kYXRlKHVuaXF1ZShmdWxsX2RhdGEkY29sbGVjdGlvbl9kYXRlKSkpCiAgCiAgY29ycl9kYXRhID0gZnVsbF9kYXRhICU+JQogICAgZmlsdGVyKHNwX25hbWUgJWluJSBudW1fY29sbHMkc3BfbmFtZSkgJT4lIAogICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogICAgaW5uZXJfam9pbihkdXJhdGlvbl90ZW1wcywgam9pbl9ieShjb2xsZWN0aW9uX2RhdGUgPT0gZGF0ZSkpICU+JSAKICAgIHBpdm90X2xvbmdlcihjb2xzID0gYyhjb2xsZWN0aW9uX3RlbXAsIGNvbnRhaW5zKCJkYXlfIikpLAogICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ2YWx1ZSIsIAogICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInByZWRpY3RvciIpICU+JSAgCiAgICBncm91cF9ieShzcF9uYW1lLCBwcmVkaWN0b3IpICU+JSAKICAgIHN1bW1hcmlzZShjb3JyZWxhdGlvbiA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkZXN0aW1hdGUsCiAgICAgICAgICAgICAgcC52YWx1ZSA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkcC52YWx1ZSwKICAgICAgICAgICAgICBjaV9sb3cgPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGNvbmYuaW50WzFdLAogICAgICAgICAgICAgIGNpX2hpZ2ggPSBjb3IudGVzdChjdG1heCwgdmFsdWUpJGNvbmYuaW50WzJdLAogICAgICAgICAgICAgIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICAgIGZpbHRlcihwcmVkaWN0b3IgIT0gImNvbGxlY3Rpb25fdGVtcCIpICU+JSAKICAgIG11dGF0ZShzaWcgPSBpZmVsc2UocC52YWx1ZSA8MC4wNSwgIlNpZy4iLCAiTm9uIFNpZy4iKSkgJT4lIAogICAgc2VwYXJhdGUocHJlZGljdG9yLCAiX2RheV8iLCBpbnRvID0gYyhOQSwgInBhcmFtZXRlciIpKSAlPiUgCiAgICBtdXRhdGUoZHVyYXRpb24gPSBpKQogIAogIGNvcnJfdmFscyA9IGJpbmRfcm93cyhjb3JyX3ZhbHMsIGNvcnJfZGF0YSkKfQoKY29sbF9jb3JyID0gZnVsbF9kYXRhICU+JQogIGZpbHRlcihzcF9uYW1lICVpbiUgbnVtX2NvbGxzJHNwX25hbWUpICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIHN1bW1hcmlzZShjb3JyZWxhdGlvbiA9IGNvci50ZXN0KGN0bWF4LCBjb2xsZWN0aW9uX3RlbXApJGVzdGltYXRlLAogICAgICAgICAgICBwLnZhbHVlID0gY29yLnRlc3QoY3RtYXgsIGNvbGxlY3Rpb25fdGVtcCkkcC52YWx1ZSwKICAgICAgICAgICAgY2lfbG93ID0gY29yLnRlc3QoY3RtYXgsIGNvbGxlY3Rpb25fdGVtcCkkY29uZi5pbnRbMV0sCiAgICAgICAgICAgIGNpX2hpZ2ggPSBjb3IudGVzdChjdG1heCwgY29sbGVjdGlvbl90ZW1wKSRjb25mLmludFsyXSkgJT4lIAogIG11dGF0ZShzaWcgPSBpZmVsc2UocC52YWx1ZSA8MC4wNSwgIlNpZy4iLCAiTm9uIFNpZy4iKSkgJT4lIAogIG11dGF0ZShkdXJhdGlvbiA9IDAsCiAgICAgICAgIHBhcmFtZXRlciA9ICJjb2xsX3RlbXAiKQoKY29ycl92YWxzID0gY29ycl92YWxzICU+JSAgCiAgbXV0YXRlKGR1cmF0aW9uID0gYXMubnVtZXJpYyhkdXJhdGlvbikpICU+JSAKICBiaW5kX3Jvd3MoY29sbF9jb3JyKQoKYGBgCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Nn0KY29ycl92YWxzICU+JSAKICBtdXRhdGUocGFyYW1ldGVyID0gZmN0X3JlbGV2ZWwocGFyYW1ldGVyLCBjKCJtaW4iLCAibWF4IiwgInJhbmdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtZWFuIiwgIm1lZCIsICJ2YXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1lYW5fbWluIiwgIm1lYW5fbWF4IiwgIm1lYW5fcmFuZ2UiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBkdXJhdGlvbiwgeSA9IGNvcnJlbGF0aW9uLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKC5+cGFyYW1ldGVyKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9wb2ludChzaXplID0gMC45KSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkR1cmF0aW9uIChkYXlzKSIsCiAgICAgICB5ID0gIkNvcnJlbGF0aW9uIiwgCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKQpgYGAKClNob3duIGhlcmUgYXJlIHRoZSB0b3AgdGhyZWUgZmFjdG9ycyBmb3IgZWFjaCBzcGVjaWVzLiAKCmBgYHtyIHByZWRpY3Rvci1jb3JyZWxhdGlvbnN9CiMgCiMgY29ycl92YWxzID0gZnVsbF9kYXRhICU+JQojICAgZmlsdGVyKHNwX25hbWUgJWluJSBudW1fY29sbHMkc3BfbmFtZSkgJT4lIAojICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAojICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzLkRhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAojICAgZnVsbF9qb2luKHRlbXBfcHJlZGljdG9ycywgam9pbl9ieShjb2xsZWN0aW9uX2RhdGUgPT0gZGF0ZSkpICU+JSAKIyAgIHBpdm90X2xvbmdlcihjb2xzID0gYyhjb2xsZWN0aW9uX3RlbXAsIG1lYW5fdGVtcDp0YWlsKG5hbWVzKC4pLCAxKSksCiMgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlIiwgCiMgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAicHJlZGljdG9yIikgJT4lICAKIyAgIGdyb3VwX2J5KHNwX25hbWUsIHByZWRpY3RvcikgJT4lIAojICAgc3VtbWFyaXNlKGNvcnJlbGF0aW9uID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRlc3RpbWF0ZSwKIyAgICAgICAgICAgICBwLnZhbHVlID0gY29yLnRlc3QoY3RtYXgsIHZhbHVlKSRwLnZhbHVlLAojICAgICAgICAgICAgIGNpX2xvdyA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMV0sCiMgICAgICAgICAgICAgY2lfaGlnaCA9IGNvci50ZXN0KGN0bWF4LCB2YWx1ZSkkY29uZi5pbnRbMl0pICU+JSAKIyAgIG11dGF0ZShzaWcgPSBpZmVsc2UocC52YWx1ZSA8MC4wNSwgIlNpZy4iLCAiTm9uIFNpZy4iKSkKCmNvcnJfdmFscyAlPiUgIAogIGZpbHRlcihzaWcgPT0gIlNpZy4iKSAlPiUgCiAgZHJvcF9uYShjb3JyZWxhdGlvbikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUpICU+JQogIGFycmFuZ2UoZGVzYyhjb3JyZWxhdGlvbikpICU+JSAKICBzbGljZV9oZWFkKG4gPSAzKSAlPiUgCiAgc2VsZWN0KCJTcGVjaWVzIiA9IHNwX25hbWUsICJQcmVkaWN0b3IiID0gcGFyYW1ldGVyLCAiRHVyYXRpb24iID0gZHVyYXRpb24sICJDb3JyZWxhdGlvbiIgPSBjb3JyZWxhdGlvbiwgIlAtVmFsdWUiID0gcC52YWx1ZSkgJT4lIAogIGtuaXRyOjprYWJsZShhbGlnbiA9ICJjIikKYGBgCgpQaGVub3R5cGljIHZhcmlhdGlvbiAobGlrZSBhY2NsaW1hdGlvbiBvZiB0aGVybWFsIGxpbWl0cykgaXMgYSBwaHlzaW9sb2dpY2FsIHByb2Nlc3MuIGRlcGVuZGluZyBvbiB0aGUgbWVjaGFuaXN0aWMgdW5kZXJwaW5uaW5ncyAoY2hhbmdlcyBpbiBIU1AgZXhwcmVzc2lvbiwgZXRjLiksIHRoZSBhbW91bnQgb2YgdGltZSBpdCB0YWtlcyBmb3IgYW4gaW5kaXZpZHVhbCB0byBhY2NsaW1hdGUgbWF5IHZhcnkgYmFzZWQgb24gYm9keSBzaXplIChsYXJnZXIgc3BlY2llcywgbW9yZSBjZWxscywgbW9yZSB0aW1lIHJlcXVpcmVkIHRvIGFjY2xpbWF0ZSkuIFNob3duIGhlcmUgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBlbnZpcm9ubWVudGFsIGFjY2xpbWF0aW9uIHdpbmRvdyB0aGUgY29wZXBvZHMgYXBwZWFyIHRvIGJlIHJlc3BvbmRpbmcgdG8uICAKCmBgYHtyIGFjYy1kdXJhdGlvbi1wbG90LCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD00fQptZWFuX3NpemVzID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lICAKICBzdW1tYXJpc2UobWVhbl9zaXplID0gbWVhbihzaXplLCBuYS5ybSA9IFQpKQoKY29ycl92YWxzICU+JSAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgZmlsdGVyKGNvcnJlbGF0aW9uID09IG1heChjb3JyZWxhdGlvbikpICU+JSAgCiAgaW5uZXJfam9pbihtZWFuX3NpemVzLCBieSA9ICJzcF9uYW1lIikgJT4lIAogIHNlbGVjdChzcF9uYW1lLCBkdXJhdGlvbiwgbWVhbl9zaXplKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IG1lYW5fc2l6ZSwgeSA9IGR1cmF0aW9uKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzcF9uYW1lKSwgCiAgICAgICAgICAgICBzaXplID0gNCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiTWVhbiBGZW1hbGUgU2l6ZSAobW0pIiwKICAgICAgIHkgPSAiQWNjbGltYXRpb24gRHVyYXRpb24iLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKCiMjIFRyYWl0IFZhcmlhdGlvbiAKYGBge3IgY3RtYXgtYW5kLXNpemUtc3VtLXBsb3QsIGZpZy53aWR0aD0yMCwgZmlnLmhlaWdodD01fQojIGN0bWF4X3Bsb3QgPSBmdWxsX2RhdGEgJT4lCiMgICBtdXRhdGUoICNzcF9uYW1lID0gc3RyX3JlcGxhY2Uoc3BfbmFtZSwgcGF0dGVybiA9ICIgIiwKIyAgICAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gIlxuIiksCiMgICAgIHNwX25hbWUgPSBmY3RfcmVvcmRlcihzcF9uYW1lLCBjdG1heCwgbWVhbikpICU+JQojICAgZ2dwbG90KGFlcyh5ID0gc3BfbmFtZSwgeCA9IGN0bWF4KSkgKwojICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPSBzcF9uYW1lX3N1YiksCiMgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjMpLAojICAgICAgICAgICAgICBzaXplID0gNCkgKwojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsKIyAgIHhsYWIoTlVMTCkgKwojICAgbGFicyh5ID0gIiIsCiMgICAgICAgIHggPSAiQ1RtYXggKMKwQykiLAojICAgICAgICBjb2xvdXIgPSAiR3JvdXAiKSArCiMgICB0aGVtZV9tYXR0KCkgKwojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQojIAojIHNpemVfcGxvdCA9IGZ1bGxfZGF0YSAlPiUKIyAgIG11dGF0ZShzcF9uYW1lID0gZmN0X3Jlb3JkZXIoc3BfbmFtZSwgY3RtYXgsIG1lYW4pKSAlPiUKIyAgIGdncGxvdChhZXMoeSA9IHNwX25hbWUsIHggPSBzaXplKSkgKwojICAgZ2VvbV9wb2ludChhZXMoY29sb3VyPSBzcF9uYW1lX3N1YiksCiMgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjMpLAojICAgICAgICAgICAgICBzaXplID0gNCkgKwojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsKIyAgIGxhYnMoeCA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKIyAgICAgICAgeSA9ICIiLAojICAgICAgICBjb2xvdXIgPSAiR3JvdXAiKSArCiMgICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQobmNvbCA9IDEpKSArCiMgICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9ICkgKwojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKIyAgICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLAojICAgICAgICAgcGxvdC5tYXJnaW4gPSBtYXJnaW4oMCwgMCwgMCwgMCwiY20iKSkKIyAKIyB0cmFpdF9wbG90ID0gY3RtYXhfcGxvdCArIHNpemVfcGxvdAojIHRyYWl0X3Bsb3QKYGBgCgpTaG93biBiZWxvdyBhcmUgdGhlIGNsdXRjaCBzaXplIGRpc3RyaWJ1dGlvbnMgZm9yIHRoZSB0aHJlZSBkaWFwdG9taWlkIHNwZWNpZXMsIHdoaWNoIHByb2R1Y2UgZWdnIHNhY3MgdGhhdCBhbGxvdyBmb3IgZWFzeSBxdWFudGlmaWNhdGlvbiBvZiBmZWN1bmRpdHkuIAoKYGBge3IgZmVjdW5kaXR5LWhpc3RvZ3JhbSwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MTB9CmZ1bGxfZGF0YSAlPiUgIAogIGRyb3BfbmEoZmVjdW5kaXR5KSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGZlY3VuZGl0eSwgZmlsbCA9IHNwX25hbWVfc3ViKSkgKyAKICBmYWNldF93cmFwKC5+c3BfbmFtZV9zdWIsIG5jb2wgPSAxKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMikgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgbGFicyh4ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIpICsKICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCk9uZSBvZiB0aGUgbWFpbiBhaW1zIG9mIHRoaXMgcHJvamVjdCBpcyB0byBleGFtaW5lIHRoZSBwYXR0ZXJucyBhbmQgcHJvY2Vzc2VzIGRyaXZpbmcgdmFyaWF0aW9uIGluIHVwcGVyIHRoZXJtYWwgbGltaXRzIGFjcm9zcyB0aGVzZSBzcGVjaWVzIG9mIGNvcGVwb2RzLiAKCiMjIyBWYXJpYXRpb24gd2l0aCB0ZW1wZXJhdHVyZSAKCldlIGV4cGVjdCBvbmUgb2YgdGhlIHByaW1hcnkgZHJpdmVycyBvZiBjb3BlcG9kIHRoZXJtYWwgbGltaXRzIHRvIGJlIHRlbXBlcmF0dXJlLiBUaGUgY29ycmVsYXRpb24gYW5hbHlzaXMgaGFzIHNob3duIHRoYXQgdGhlIGNvcGVwb2RzIGFyZSBnZW5lcmFsbHkgKGFsdGhvdWdoIG5vdCBhbHdheXMpIHJlc3BvbmRpbmcgdG8gdGhlIHJlY2VudCB0aGVybWFsIGVudmlyb25tZW50LiBTaG93biBiZWxvdyBhcmUgdGhlcm1hbCBsaW1pdHMsIGJvZHkgc2l6ZSwgYW5kIGZlY3VuZGl0eSB2YWx1ZXMgcGxvdHRlZCBhZ2FpbnN0IHRoZSB0ZW1wZXJhdHVyZSBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uLiBBbHNvIHNob3duIGlzIHdhcm1pbmcgdG9sZXJhbmNlLCBjYWxjdWxhdGVkIGFzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdXBwZXIgdGhlcm1hbCBsaW1pdCBhbmQgdGhlIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIAoKV2UgZ2VuZXJhbGx5IHNlZSBhbiBpbmNyZWFzZSBpbiB0aGVybWFsIGxpbWl0cyB3aXRoIGluY3JlYXNpbmcgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSwgYSBzbGlnaHQgZGVjcmVhc2UgaW4gYm9keSBzaXplLCBhbmQgdmFyaWFibGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRlbXBlcmF0dXJlIGFuZCBmZWN1bmRpdHkuIEFsbCBzcGVjaWVzIG1haW50YWluZWQgc29tZSBkZWdyZWUgb2YgYnVmZmVyIGJldHdlZW4gZW52aXJvbm1lbnRhbCB0ZW1wZXJhdHVyZXMgYW5kIHVwcGVyIHRoZXJtYWwgbGltaXRzLCBidXQgKkVwaXNjaHVyYSogYW5kICpMLiBtaW51dHVzKiBhcHByb2FjaGVkIHRoZWlyIHVwcGVyIHRoZXJtYWwgbGltaXRzIGR1cmluZyB0aGUgd2FybWVzdCBjb2xsZWN0aW9ucyBkdXJpbmcgdGhlIHN1bW1lci4gCgpgYGB7ciB0cmFpdC1jb2xsLXRlbXAtcGxvdHMsIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KY3RtYXhfdGVtcCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKc2l6ZV90ZW1wID0gZ2dwbG90KGZpbHRlcihmdWxsX2RhdGEsIHNleCAhPSAianV2ZW5pbGUiKSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBzaXplLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBsaW5ld2lkdGggPSAzKSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBsYWJzKHggPSAiQ29sbGVjdGlvbiBUZW1wZXJhdHVyZSAowrBDKSIsIAogICAgICAgeSA9ICJMZW5ndGggKG1tKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgp3dF90ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSB3YXJtaW5nX3RvbCwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgbGluZXdpZHRoID0gMykgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcGVyYXR1cmUgKMKwQykiLCAKICAgICAgIHkgPSAiV2FybWluZyBUb2xlcmFuY2UgKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSAgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZWdnc190ZW1wID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBmZWN1bmRpdHksIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGxpbmV3aWR0aCA9IDMpICsKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXBlcmF0dXJlICjCsEMpIiwgCiAgICAgICB5ID0gIkZlY3VuZGl0eSAoIyBFZ2dzKSIsCiAgICAgICBjb2xvdXIgPSAiU3BlY2llcyIpICArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfdGVtcCwgc2l6ZV90ZW1wLCB3dF90ZW1wLCBlZ2dzX3RlbXAsIAogICAgICAgICAgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJyaWdodCIpCmBgYAoKYGBge3IgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9NX0KZnVsbF9kYXRhICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgZmlsdGVyKG4oKSA+IDUpICU+JSBmaWx0ZXIoIXN0cl9kZXRlY3Qoc3BfbmFtZSwgcGF0dGVybiA9ICJraW5kdGkiKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuOCkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpUZW1wZXJhdHVyZSBkZXBlbmRlbmNlIGlzIHJlbGF0aXZlbHkgd2VhayBpbiAqTC4gc2ljaWxpcyosIGVzcGVjaWFsbHkgYXQgY29vbGVyIHRlbXBlcmF0dXJlcy4gV2Ugd2lsbCByZXR1cm4gdG8gdGhpcyBmZWF0dXJlIGxhdGVyIGluIHRoZSByZXBvcnQsIGJ1dCBmb3Igbm93IHdlIHdpbGwgbm90ZSB0aGF0IHRoZXJlIGFyZSB0d28gc2l6ZSBtb3JwaHMgaW4gdGhpcyBzcGVjaWVzLCB3aGljaCBhcHBlYXIgdG8gcmVzcG9uZCBkaWZmZXJlbnRseSB0byBkZWNyZWFzZXMgaW4gdGVtcGVyYXR1cmUuIFRoZXJlIGFyZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBtb3JwaHMgYW5kIGhvdyB0ZW1wZXJhdHVyZSBhZmZlY3RzIENUbWF4LiAKCmBgYHtyfQptb3JwaF9kYXRhID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiICYgc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIpICU+JSAKICBtdXRhdGUobW9ycGggPSBpZl9lbHNlKHNpemUgPiAwLjg5LCAibGFyZ2UiLCAic21hbGwiKSkKCmdncGxvdChtb3JwaF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IGN0bWF4LCBjb2xvdXIgPSBtb3JwaCkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjgpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULCBsaW5ld2lkdGggPSAyKSArIAogIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgptb3JwaC5tb2RlbCA9IGxtKGRhdGEgPSBtb3JwaF9kYXRhLCAKICAgICAgICAgICAgICAgICBjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCAqIG1vcnBoKQoKa25pdHI6OmthYmxlKGNhcjo6QW5vdmEobW9ycGgubW9kZWwsIHR5cGUgPSAiSUlJIiwgdGVzdCA9ICJGIikpCgojc3VtbWFyeShtb3JwaC5tb2RlbCkKCiNtb3JwaC5lbSA9IGVtbWVhbnM6OmVtbWVhbnMobW9ycGgubW9kZWwsIHBhaXJ3aXNlIH4gbW9ycGgpCgojcGxvdChtb3JwaC5lbSkKYGBgCgpgYGB7ciBjdG1heC1yYW5nZS1wbG90LCBpbmNsdWRlID0gRn0KZnVsbF9kYXRhICU+JSAgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIGNvbGxlY3Rpb25fZGF0ZSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgIAogIHN1bW1hcmlzZSgiY3RtYXhfcmFuZ2UiID0gbWF4KGN0bWF4KSAtIG1pbihjdG1heCksCiAgICAgICAgICAgICJjdG1heF92YXIiID0gdmFyKGN0bWF4KSwKICAgICAgICAgICAgInNhbXBsZV9zaXplIiA9IG4oKSkgJT4lIAogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIAogIGZpbHRlcihzcF9uYW1lICE9ICJMZXB0b2RvcmEga2luZHRpIikgJT4lIAogIGZpbHRlcihzYW1wbGVfc2l6ZSA+IDMpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heF92YXIsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG91ciA9ICJibGFjayIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKQpgYGAKCgpgYGB7ciBjdG1heC1jb2xsLXRlbXAtbW9kZWwsIGluY2x1ZGUgPSBGfQojIGFkdWx0X2RhdGEgPSBmdWxsX2RhdGEgJT4lIAojICAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikKbW9kZWxfZGF0YSA9IGZ1bGxfZGF0YSAlPiUgIAogIGRyb3BfbmEoc2l6ZSwgY3RtYXgpICU+JSAgCiAgbXV0YXRlKHRlbXBfY2VudCA9IHNjYWxlKGNvbGxlY3Rpb25fdGVtcCwgY2VudGVyID0gVCwgc2NhbGUgPSBGKSwKICAgICAgICAgc2l6ZV9jZW50ID0gc2NhbGUoc2l6ZSwgY2VudGVyID0gVCwgc2NhbGUgPSBGKSkKCmN0bWF4X3RlbXAubW9kZWwgPSBsbShkYXRhID0gbW9kZWxfZGF0YSwgY3RtYXggfiB0ZW1wX2NlbnQgKiBzcF9uYW1lKQpzaXplX3RlbXAubW9kZWwgPSBsbShkYXRhID0gbW9kZWxfZGF0YSwgc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCAqIHNwX25hbWUpCgprbml0cjo6a2FibGUoY2FyOjpBbm92YShjdG1heF90ZW1wLm1vZGVsKSkKCmN0bWF4X3Jlc2lkcyA9IGNiaW5kKG1vZGVsX2RhdGEsICJyZXNpZHMiID0gY3RtYXhfdGVtcC5tb2RlbCRyZXNpZHVhbHMsICJzaXplX3Jlc2lkcyIgPSBzaXplX3RlbXAubW9kZWwkcmVzaWR1YWxzKQoKYGBgCgpDb3BlcG9kcyBzcGVudCBzZXZlcmFsIGRheXMgaW4gbGFiIGR1cmluZyBleHBlcmltZW50cy4gU2hvd24gYmVsb3cgYXJlIHRoZSBDVG1heCByZXNpZHVhbHMgKHRha2VuIGZyb20gYSBtb2RlbCBvZiBDVG1heCBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUpIHBsb3R0ZWQgYWdhaW5zdCB0aGUgdGltZSBzcGVudCBpbiBsYWIgYmVmb3JlIG1lYXN1cmVtZW50cyB3ZXJlIG1hZGUuIEluZGl2aWR1YWwgcmVncmVzc2lvbnMgYXJlIHNob3duIGZvciB0aGUgcmVzaWR1YWxzIGFnYWluc3QgZGF5cyBpbiBsYWIgZm9yIGVhY2ggY29sbGVjdGlvbi4gV2UgY2FuIHNlZSBjbGVhcmx5IHRoYXQgdGhlcm1hbCBsaW1pdHMgYXJlIGZhaXJseSBzdGFibGUgb3ZlciB0aW1lLiAKCmBgYHtyIGN0bWF4LXRpbWUtaW4tbGFiLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9MTB9CmdncGxvdChjdG1heF9yZXNpZHMsIGFlcyh4ID0gZGF5c19pbl9sYWIsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUsIGdyb3VwID0gY29sbGVjdGlvbl9kYXRlKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0LCBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDEpICsgCiAgI3NjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDA6NSkpICsgCiAgbGFicyh4ID0gIkRheXMgaW4gbGFiIiwgCiAgICAgICB5ID0gIkNUbWF4IFJlc2lkdWFscyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpgYGB7ciBpbmNsdWRlID0gRn0KY3RtYXhfcmVzaWRzICU+JSAKICBmaWx0ZXIobGlwaWRzICE9ICJ1bmNlcnRhaW4iKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gbGlwaWRzLCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0LCBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDEpICsgCiAgI3NjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDA6NSkpICsgCiAgbGFicyh4ID0gIkRheXMgaW4gbGFiIiwgCiAgICAgICB5ID0gIkNUbWF4IFJlc2lkdWFscyIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpgYGB7ciBBUlItbGltaXRzLXBsb3QsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTZ9CmZ1bGwubW9kZWwgPSBsbWU0OjpsbWVyKGRhdGEgPSBtb2RlbF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBjdG1heCB+IHNleCArIHRlbXBfY2VudCArIHNpemVfY2VudCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgKyBkYXlzX2luX2xhYiArIHRlbXBfY2VudCArIHNpemVfY2VudHxzcF9uYW1lKSkKCmNhcjo6QW5vdmEoZnVsbC5tb2RlbCkKCmZpeGVkID0gZml4ZWYoZnVsbC5tb2RlbCkKCm1vZGVsX2NvZWZzID0gY29lZmZpY2llbnRzKGZ1bGwubW9kZWwpJGBzcF9uYW1lYCAlPiUgIAogIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAic3BlY2llcyIpICU+JSAKICBzZXBhcmF0ZShzcGVjaWVzLCBpbnRvID0gYygic3BlY2llcyIpLCBzZXAgPSAiOiIpICU+JSAKICBzZWxlY3Qoc3BlY2llcywgImludGVyY2VwdCIgPSAiKEludGVyY2VwdCkiLCB0ZW1wX2NlbnQsIHNpemVfY2VudCwgZGF5c19pbl9sYWIpCgpnZ3Bsb3QobW9kZWxfY29lZnMsIGFlcyh4ID0gaW50ZXJjZXB0LCB5ID0gdGVtcF9jZW50KSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc3BlY2llcyksCiAgICAgICAgICAgICBzaXplID0gNikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICBsYWJzKHggPSAiU3BlY2llcyBJbnRlcmNlcHQiLCAKICAgICAgIHkgPSAiQVJSIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKClRoZSB0ZXJtICJhY2NsaW1hdGlvbiByZXNwb25zZSByYXRpbyIgaXMgb2Z0ZW4gdXNlZCB0byBkZXNjcmliZSB0aGUgZWZmZWN0IG9mIHRlbXBlcmF0dXJlIG9uIHRoZXJtYWwgbGltaXRzLiBUaGUgQVJSIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIGNoYW5nZSBpbiB0aGVybWFsIGxpbWl0cyBwZXIgZGVncmVlIGNoYW5nZSBpbiBhY2NsaW1hdGlvbiB0ZW1wZXJhdHVyZS4gRm9yIG91ciBkYXRhLCB3ZSB3aWxsIGVzdGltYXRlIEFSUiBhcyB0aGUgc2xvcGUgb2YgQ1RtYXggYWdhaW5zdCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLiBUaGVzZSBzbG9wZXMgd2VyZSB0YWtlbiBmcm9tIGEgcmVncmVzc2lvbiBvZiBDVG1heCBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgYW5kIGJvZHkgc2l6ZS4gVHdvIGRpZmZlcmVudCBtb2RlbCB0eXBlcyB3ZXJlIHVzZWQsIGEgc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIGFuZCBhIG1peGVkIGVmZmVjdHMgbW9kZWwuIFRoZSBlc3RpbWF0ZWQgQVJSIHZhbHVlcyB3ZXJlIGdlbmVyYWxseSBoaWdobHkgc2ltaWxhciBiZXR3ZWVuIHRoZSBtb2RlbCB0eXBlcyB1c2VkLgoKYGBge3IgYXJyLWNvbXAtcGxvdCwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTAsIGluY2x1ZGUgPSBGfQpjb2VmX21vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lIAogIGZpbHRlcihuKCkgPiAzICYgIXN0cl9kZXRlY3Qoc3BfbmFtZSwgcGF0dGVybiA9ICJraW5kdGkiKSkgCgpjb2VmX24gPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lIAogIGZpbHRlcihuKCkgPiA1KSAlPiUgCiAgc3VtbWFyaXNlKHNhbXBsZV9uID0gbigpLCAKICAgICAgICAgICAgbWVhbl9jdG1heCA9IG1lYW4oY3RtYXgpKQoKQVJSX3ZhbHMgPSBjb2VmX21vZGVsX2RhdGEgJT4lIAogIGRvKGJyb29tOjp0aWR5KGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc2l6ZSwgZGF0YSA9IC4pKSkgJT4lIAogIGZpbHRlcih0ZXJtID09ICJjb2xsZWN0aW9uX3RlbXAiKSAlPiUgCiAgc2VsZWN0KHNwX25hbWUsIHNleCwgIkFSUiIgPSBlc3RpbWF0ZSwgc3RkLmVycm9yKSAlPiUgCiAgYXJyYW5nZShBUlIpICU+JSAKICBpbm5lcl9qb2luKGNvZWZfbiwgYnkgPSBjKCJzcF9uYW1lIiwgInNleCIpKQoKQVJSX3ZhbHMgJT4lIAogIHNlbGVjdCgiU3BlY2llcyIgPSBzcF9uYW1lLCAKICAgICAgICAgIkdyb3VwIiA9IHNleCwgCiAgICAgICAgICJOIiA9IHNhbXBsZV9uLAogICAgICAgICBBUlIsIAogICAgICAgICAiRXJyb3IiID0gc3RkLmVycm9yKSAlPiUgCiAga25pdHI6OmthYmxlKCkKCm1sZV9jb2VmcyA9IGNvZWZmaWNpZW50cyhmdWxsLm1vZGVsKSRgc3BfbmFtZWAgJT4lIAogIG11dGF0ZSgiZ3JvdXAiID0gcm93bmFtZXMoLikpICU+JSAKICBzZWxlY3QoZ3JvdXAsICJpbnRlcmNlcHQiID0gIihJbnRlcmNlcHQpIiwgIkFSUiIgPSB0ZW1wX2NlbnQsIHNpemVfY2VudCkgJT4lIAogIHJlbW92ZV9yb3duYW1lcygpCgptbGVfQVJSID0gbWxlX2NvZWZzICU+JSAgCiAgc2VsZWN0KHNwX25hbWUgPSBncm91cCwgQVJSKSAlPiUgCiAgbXV0YXRlKCJtb2RlbCIgPSAibWl4ZWQgZWZmZWN0cyIpICAlPiUgCiAgaW5uZXJfam9pbihjb2VmX24sIGJ5ID0gYygic3BfbmFtZSIpKQoKQVJSX2NvbXAgPSBiaW5kX3Jvd3MobWxlX0FSUiwgCiAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShBUlJfdmFscywgIm1vZGVsIiA9ICJsaW5lYXIiKSkKCkFSUl9jb21wICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBtb2RlbCwgeSA9IEFSUiwgZ3JvdXAgPSBzcF9uYW1lKSkgKyAKICBmYWNldF9ncmlkKHNwX25hbWV+c2V4KSArCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMS41KSArIAogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsIDAuNSwgMSkpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKCmBgYAoKIyMjIFNleCBhbmQgc3RhZ2UgdmFyaWF0aW9uIGluIHRoZXJtYWwgbGltaXRzIApQcmV2aW91cyBzZWN0aW9ucyBoYXZlIGdlbmVyYWxseSBsdW1wZWQganV2ZW5pbGUsIGZlbWFsZSwgYW5kIG1hbGUgaW5kaXZpZHVhbHMgdG9nZXRoZXIuIFRoZXJlIG1heSBiZSBpbXBvcnRhbnQgc3RhZ2UtIG9yIHNleC1zcGVjaWZpYyBkaWZmZXJlbmNlcyBpbiBDVG1heCB0aG91Z2guIEZvciBzZXZlcmFsIHNwZWNpZXMsIHdlIGhhdmUgbWVhc3VyZW1lbnRzIGZvciBpbmRpdmlkdWFscyBpbiBkaWZmZXJlbnQgc3RhZ2VzIG9yIG9mIGRpZmZlcmVudCBzZXhlcy4gCgpgYGB7ciBzZXgtc3RhZ2UtdGFibGV9CnNleF9zYW1wbGVfc2l6ZXMgPSBjdG1heF9yZXNpZHMgJT4lICAKICBncm91cF9ieShzcF9uYW1lLCBzZXgpICU+JSAgCiAgc3VtbWFyaXNlKG51bSA9IG4oKSkgJT4lICAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gc3BfbmFtZSwKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gc2V4LCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IG51bSwKICAgICAgICAgICAgICB2YWx1ZXNfZmlsbCA9IDApICU+JSAKICBzZWxlY3QoIlNwZWNpZXMiID0gc3BfbmFtZSwgIkp1dmVuaWxlIiA9IGp1dmVuaWxlLCAiRmVtYWxlIiA9IGZlbWFsZSwgIk1hbGUiID0gbWFsZSkKCmtuaXRyOjprYWJsZShzZXhfc2FtcGxlX3NpemVzLCBhbGlnbiA9ICJjIikKYGBgCgpUaGUgZmVtYWxlLW1hbGUgYW5kIGZlbWFsZS1qdXZlbmlsZSBjb21wYXJpc29ucyBzaG93IHRoYXQgdGhlcmUgYXJlIGdlbmVyYWxseSBubyBkaWZmZXJlbmNlcyBpbiB0aGVybWFsIGxpbWl0cyBiZXR3ZWVuIHRoZXNlIGdyb3Vwcy4gCgpgYGB7ciBjdG1heC1zZXgsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTd9CmN0bWF4X3Jlc2lkcyAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBmaWx0ZXIoc2V4X3NhbXBsZV9zaXplcywgTWFsZSA+IDAsIEZlbWFsZSA+IDApJFNwZWNpZXMgJiAKICAgICAgICAgICBzZXggIT0gImp1dmVuaWxlIikgJT4lIAogIGdncGxvdChhZXMoeCA9IHNleCwgeSA9IHJlc2lkcywgY29sb3VyID0gc3BfbmFtZSwgZ3JvdXAgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LiwgbmNvbCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyKGhlaWdodCA9IDAsIHdpZHRoID0gMC4wNSkpICsgIAogIGxhYnMoeCA9ICJTZXgiLCAKICAgICAgIHkgPSAiQ1RtYXggUmVzaWR1YWxzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9idyhiYXNlX3NpemUgPSAxOCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3IgY3RtYXgtc3RhZ2UsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTd9CmN0bWF4X3Jlc2lkcyAlPiUgCiAgZmlsdGVyKHNwX25hbWUgJWluJSBmaWx0ZXIoc2V4X3NhbXBsZV9zaXplcywgSnV2ZW5pbGUgPiAwICYgRmVtYWxlID4gMCkkU3BlY2llcyAmIAogICAgICAgICAgIHNleCAhPSAibWFsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzZXgsIHkgPSByZXNpZHMsIGNvbG91ciA9IHNwX25hbWUsIGdyb3VwID0gc3BfbmFtZSkpICsgCiAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIG5jb2wgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcihoZWlnaHQgPSAwLCB3aWR0aCA9IDAuMDUpKSArICAKICBsYWJzKHggPSAiU2V4IiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9idyhiYXNlX3NpemUgPSAxOCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3IgdHJhaXQtdmFyaWFuY2UtY29sbC10ZW1wLCBpbmNsdWRlID0gRn0KIyAKIyBHaXZlbiB0aGUgbG9uZyBnZW5lcmF0aW9uIHRpbWVzIG9mIHRoZXNlIGNvcGVwb2RzLCBkZWNyZWFzZXMgaW4gdHJhaXQgdmFyaWFuY2UgbWF5IGluZGljYXRlIHNlbGVjdGlvbiBvdmVyIHRoZSBzZWFzb25hbCBjeWNsZS4gU2hvd24gYmVsb3cgYXJlIHRoZSB2YXJpYW5jZSBpbiBvYnNlcnZlZCBDVG1heCBhbmQgc2l6ZSwgcGxvdHRlZCBhZ2FpbnN0IGNvbGxlY3Rpb24gZGF0ZS4gVmFyaWFuY2UgZGVjcmVhc2VzIGluICpTa2lzdG9kaWFwdG9tdXMqLCBidXQgdGhpcyBwYXR0ZXJuIGlzIGRyaXZlbiBieSBhIHNpbmdsZSBjb2xsZWN0aW9uIHdpdGggaGlnaCB2YXJpYW5jZSBlYXJseSBpbiB0aGUgeWVhci4gU2l6ZSB2YXJpYW5jZSBpbmNyZWFzZXMgc2xpZ2h0bHkgaW4gKlNraXN0b2RpYXB0b211cyouIFZhcmlhbmNlIGluIGJvdGggQ1RtYXggYW5kIHNpemUgaXMgZmFpcmx5IGNvbnN0YW50IGluICpMZXB0b2RpYXB0b211cyBtaW51dHVzKiwgdGhlIG9ubHkgb3RoZXIgc3BlY2llcyBjb2xsZWN0ZWQgYWNyb3NzIHRoZSBlbnRpcmUgc2V0IG9mIHNhbXBsZXMgdGh1cyBmYXIuIAojIAojIGdncGxvdChkcm9wX25hKGFkdWx0X3N1bW1hcmllcywgY3RtYXhfdmFyKSwgYWVzKHggPSBhcy5EYXRlKGNvbGxlY3Rpb25fZGF0ZSksIHkgPSBjdG1heF92YXIsIGNvbG91ciA9IHNwX25hbWUpKSArIAojICAgZmFjZXRfd3JhcChzcF9uYW1lfi4sIHNjYWxlcyA9ICJmcmVlX3kiKSArIAojICAgZ2VvbV9wb2ludChzaXplID0gMikgKyAKIyAgIGdlb21fc21vb3RoKHNlID0gRikgKyAKIyAgIGxhYnMoeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIiwgCiMgICAgICAgIHkgPSAiQ1RtYXggVmFyaWFuY2UiKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzcGVjaWVzX2NvbHMpICsgCiMgICB0aGVtZV9tYXR0X2ZhY2V0cygpICsgCiMgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCiMgCiMgZ2dwbG90KGRyb3BfbmEoYWR1bHRfc3VtbWFyaWVzLCBzaXplX3ZhciksIGFlcyh4ID0gYXMuRGF0ZShjb2xsZWN0aW9uX2RhdGUpLCB5ID0gc2l6ZV92YXIsIGNvbG91ciA9IHNwX25hbWUpKSArIAojICAgZmFjZXRfd3JhcChzcF9uYW1lfi4pICsgCiMgICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAojICAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAojICAgbGFicyh4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiLCAKIyAgICAgICAgeSA9ICJTaXplIFZhcmlhbmNlIikgKyAKIyAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAojICAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAojICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKQpgYGAKCgojIyMgVHJhaXQgQ29ycmVsYXRpb25zIGFuZCBUcmFkZS1vZmZzCgpBIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNpemUgYW5kIHVwcGVyIHRoZXJtYWwgbGltaXRzIGhhcyBiZWVuIHN1Z2dlc3RlZCBpbiBhIHdpZGUgcmFuZ2Ugb2Ygb3RoZXIgdGF4YS4gU2hvd24gYmVsb3cgYXJlIHRoZSBtZWFzdXJlZCB1cHBlciB0aGVybWFsIGxpbWl0cyBwbG90dGVkIGFnYWluc3QgcHJvc29tZSBsZW5ndGguIFRoZSBvdmVyYWxsIHJlbGF0aW9uc2hpcCAoaW5jbHVzaXZlIG9mIGFsbCBzcGVjaWVzKSBpcyBzaG93biBhcyB0aGUgYmxhY2sgbGluZSBpbiB0aGUgYmFja2dyb3VuZC4gUmVncmVzc2lvbnMgZm9yIGVhY2ggaW5kaXZpZHVhbCBzcGVjaWVzIGFyZSBhbHNvIHNob3duLiBBY3Jvc3MgdGhlIGVudGlyZSBhc3NlbWJsYWdlLCB0aGVyZSBpcyBhIHN0cm9uZyBkZWNyZWFzZSBpbiB0aGVybWFsIGxpbWl0cyB3aXRoIGluY3JlYXNpbmcgc2l6ZS4gIAoKYGBge3IgY3RtYXgtc2l6ZSwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTd9CgpmdWxsX2RhdGEgJT4lIAogICNmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgIAogIGdncGxvdCggYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGdlb21fc21vb3RoKGRhdGEgPSBmdWxsX2RhdGEsIAogICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAgICAgICAgICAgICBjb2xvdXIgPSJibGFjayIsIAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyLCBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgbGFicyh4ID0gIkxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKYGBgCgpTaG93biBoZXJlIGlzIHRoZSByZWxhdGlvbnNoaXAgZm9yIGVhY2ggc3BlY2llcyBpbmRpdmlkdWFsbHkuIAoKYGBge3IgaW5kLXNwLWN0bWF4LXNpemUsIGZpZy53aWR0aD05LCBmaWcuaGVpZ2h0PTZ9CmZ1bGxfZGF0YSAlPiUgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lIGZpbHRlcihuKCkgPjIpICU+JSBmaWx0ZXIoIXN0cl9kZXRlY3Qoc3BfbmFtZSwgcGF0dGVybiA9ICJraW5kdGkiKSkgJT4lIAogIGdncGxvdCggYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNwX25hbWUpKSArIAogIGZhY2V0X3dyYXAoc3BfbmFtZX4uLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC44KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgY29sb3VyID0gIlNwZWNpZXMiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpTaG93biBiZWxvdyBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWVhbiBzaXplIGFuZCBtZWFuIHRoZXJtYWwgbGltaXRzIGZvciBmZW1hbGVzIG9mIGVhY2ggc3BlY2llcy4gV2Ugc2VlIHRoYXQgbGFyZ2VyIHNwZWNpZXMgd2l0aGluIHRoZSBjb21tdW5pdHkgdGVuZCB0byBoYXZlIGEgbG93ZXIgdGhlcm1hbCBsaW1pdCB0aGFuIHNtYWxsZXIgc3BlY2llcy4gCgpgYGB7ciBtZWFuLWN0bWF4LW1lYW4tc2l6ZS1wbG90LCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD01fQpmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNwX25hbWUsIHNleCkgJT4lIAogIHN1bW1hcml6ZShtZWFuX2N0bWF4ID0gbWVhbihjdG1heCwgbmEucm0gPSBUKSwKICAgICAgICAgICAgbWVhbl9zaXplID0gbWVhbihzaXplLCBuYS5ybSA9IFQpKSAlPiUgCiAgI2ZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBtZWFuX3NpemUsIHkgPSBtZWFuX2N0bWF4KSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIsIGNvbG91ciA9ICJibGFjayIpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc3BfbmFtZSwgc2hhcGUgPSBzZXgpLAogICAgICAgICAgICAgc2l6ZSA9IDUpICsgCiAgbGFicyh4ID0gIkxlbmd0aCAobW0pIiwgCiAgICAgICB5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCmBgYHtyIGN0bWF4cmVzaWRzLXNpemUsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03LCBpbmNsdWRlID0gRn0KY3RtYXhfcmVzaWRzICU+JSAKICAjZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lIAogIGdncGxvdChhZXMoeCA9IHNpemVfcmVzaWRzLCB5ID0gcmVzaWRzLCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBmYWNldF93cmFwKHNwX25hbWV+LikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAyKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwgbGluZXdpZHRoID0gMikgKyAKICBsYWJzKHggPSAiTGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiQ1RtYXggKMKwQykiKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc3BlY2llc19jb2xzKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikKYGBgCgpTaG93biBoZXJlIGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBmZWN1bmRpdHkgYW5kIHNpemUsIHNob3dpbmcgdGhlIGNsYXNzaWMgcGF0dGVybiBvZiBpbmNyZWFzaW5nIGVnZyBwcm9kdWN0aW9uIHdpdGggaW5jcmVhc2luZyBzaXplLiAKCmBgYHtyIGZlY3VuZGl0eS1zaXplLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KY3RtYXhfcmVzaWRzICU+JSAgCiAgZHJvcF9uYShmZWN1bmRpdHkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gZmVjdW5kaXR5LCBjb2xvdXIgPSBzcF9uYW1lKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjUpICsgCiAgbGFicyh4ID0gIlByb3NvbWUgbGVuZ3RoIChtbSkiLCAKICAgICAgIHkgPSAiRmVjdW5kaXR5ICgjIEVnZ3MpIiwKICAgICAgIGNvbG91ciA9ICJTcGVjaWVzIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQpgYGAKCkluZGl2aWR1YWxzIG1heSBhbHNvIGFsbG9jYXRlIGVuZXJneSB0byBkaWZmZXJlbnQgZml0bmVzcyByZWxhdGVkIHRyYWl0cywgcHJpb3JpdGl6aW5nIHJlcHJvZHVjdGl2ZSBvdXRwdXQgb3ZlciBlbnZpcm9ubWVudGFsIHRvbGVyYW5jZSwgZm9yIGV4YW1wbGUuIFNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBDVG1heCByZXNpZHVhbHMgKGFnYWluLCBjb250cm9sbGluZyBmb3IgdGhlIGVmZmVjdHMgb2YgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkgYWdhaW5zdCBmZWN1bmRpdHkuIFdlIGNhbiBzZWUgY2xlYXJseSB0aGF0IGluZGl2aWR1YWxzIHdpdGggaW5jcmVhc2VkIGZlY3VuZGl0eSBhcmUgbm90IGRlY3JlYXNpbmcgdGhlcm1hbCBsaW1pdHMsIHN1Z2dlc3RpbmcgdGhhdCB0aGVyZSBpcyBubyBlbmVyZ2V0aWMgdHJhZGUtb2ZmIGJldHdlZW4gdGhlc2UgdHJhaXRzLiAKCmBgYHtyLCBjdG1heC1mZWN1bmRpdHksIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD03fQpjdG1heF9yZXNpZHMgJT4lICAKICBkcm9wX25hKGZlY3VuZGl0eSkgJT4lIAogIGdncGxvdChhZXMoeCA9IHJlc2lkcywgeSA9IGZlY3VuZGl0eSwgY29sb3VyID0gc3BfbmFtZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGLCBsaW5ld2lkdGggPSAyKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC41KSArIAogIGxhYnMoeCA9ICJDVG1heCBSZXNpZHVhbHMiLCAKICAgICAgIHkgPSAiRmVjdW5kaXR5ICgjIEVnZ3MpIikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNwZWNpZXNfY29scykgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZml0bmVzcy5tb2RlbCA9IGxtKGRhdGEgPSBjdG1heF9yZXNpZHMsIAogICAgICAgICAgICAgICAgICAgZmVjdW5kaXR5IH4gcmVzaWRzICogc3BfbmFtZSkKCmNhcjo6QW5vdmEoZml0bmVzcy5tb2RlbCkKCmVtbWVhbnM6OmVtdHJlbmRzKGZpdG5lc3MubW9kZWwsICB2YXIgPSAicmVzaWRzIiwic3BfbmFtZSIpCmBgYAoKIyMgT3RoZXIgcGF0dGVybnMgaW4gdmFyaWF0aW9uIAoKKkxlcHRvZGlhcHRvbXVzIHNpY2lsaXMqIGlzIHRoZSBtb3N0IGFidW5kYW50IHNwZWNpZXMgZHVyaW5nIHRoZSB3aW50ZXIuIFRoZXJlIHdhcyBhIGxhcmdlIHNoaWZ0IGluIHRoZSBzaXplIG9mIG1hdHVyZSBmZW1hbGVzIHRvd2FyZHMgdGhlIGVuZCBvZiBEZWNlbWJlci4gVGhlc2UgbGFyZ2UgYW5kIHNtYWxsIGluZGl2aWR1YWxzIGFyZSB0aGUgc2FtZSBzcGVjaWVzIChjb25maXJtZWQgdmlhIENPSSBzZXF1ZW5jaW5nKSwgc3VnZ2VzdGluZyB0aGlzIHNoaWZ0IG1heSByZWZsZWN0IGEgdHJhbnNpdGlvbiBmcm9tIG9uZSBnZW5lcmF0aW9uIHRvIGFub3RoZXIgYW5kIHRoYXQsIHVubGlrZSBpbiBtYW55IG90aGVyIGxha2VzLCB0aGVyZSBhcmUgdHdvIGdlbmVyYXRpb25zIG9mICpMLiBzaWNpbGlzKiBwZXIgeWVhciBpbiBMYWtlIENoYW1wbGFpbi4gVGhpcyBzaXplIGRpZmZlcmVuY2UgbWF5IGJlIGNhdXNlZCBieSBkaWZmZXJlbmNlcyBpbiB0aGUgZGV2ZWxvcG1lbnRhbCBlbnZpcm9ubWVudHMuIEZvciBleGFtcGxlLCBpbmRpdmlkdWFscyBkZXZlbG9waW5nIGluIEphbnVhcnkgZ3JvdyB1cCBhdCB2ZXJ5IGxvdyB0ZW1wZXJhdHVyZXMsIGFuZCB0aGVyZWZvcmUgbWF5IHJlYWNoIGxhcmdlciBzaXplcy4gVGhlc2UgaW5kaXZpZHVhbHMgb3ZlcnN1bW1lciBpbiBkZWVwIHdhdGVycywgdGhlbiByZS1lbWVyZ2UgaW4gT2N0b2JlciBhbmQgcHJvZHVjZSBhIG5ldyBnZW5lcmF0aW9uLiBXYXRlciB0ZW1wZXJhdHVyZXMgYXJlIHN0aWxsIGZhaXJseSBoaWdoIHRocm91Z2ggTm92ZW1iZXIsIHdoaWNoIHJlc3VsdHMgaW4gYSBnZW5lcmF0aW9uIG9mIHNtYWxsZXIgaW5kaXZpZHVhbHMsIHdoaWNoIG1hdHVyZSBpbiB0aW1lIHRvIHByb2R1Y2UgYSBuZXcgZ2VuZXJhdGlvbiBpbiBKYW51YXJ5LiAKClNob3duIGJlbG93IGlzIHRoZSBkaXN0cmlidXRpb24gb2YgcGFpcndpc2UgZGlzdGFuY2VzIGJldHdlZW4gQ09JIHNlcXVlbmNlcyBvZiBsYXJnZSBhbmQgc21hbGwgbW9ycGhzLiBEaXN0YW5jZXMgaW4gYm90aCB3aXRoaW4tIGFuZCBhY3Jvc3MtbW9ycGggY29tcGFyaXNvbnMgYXJlIHNtYWxsLiAKCmBgYHtyfQppbmRfZGlzdCA9IGFwZTo6ZGlzdC5kbmEoc2ljX2RuYWJpbiwgbW9kZWwgPSAicmF3IikgJT4lIGFzLm1hdHJpeCAlPiUgCiAgYXNfdGliYmxlKCkgJT4lCiAgbXV0YXRlKCJpbmQxIiA9IGNvbG5hbWVzKC4pKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKC1pbmQxLCBuYW1lc190byA9ICJpbmQyIiwgdmFsdWVzX3RvID0gImRpc3QiKSAlPiUKICBtdXRhdGUoaW5kMSA9IGZhY3RvcihpbmQxKSwKICAgICAgICAgaW5kMiA9IGZhY3RvcihpbmQyKSkgJT4lIAogIGZpbHRlcighKGluZDEgPT0gInNvcmUxIiB8IGluZDIgPT0gInNvcmUxIikpICU+JSAKICBtdXRhdGUoCiAgICBpbmQxID0gY2FzZV93aGVuKAogICAgICBpbmQxID09ICJTMSIgfiAic21hbGwxIiwKICAgICAgaW5kMSA9PSAiUzMiIH4gInNtYWxsMyIsCiAgICAgIGluZDEgPT0gImxzaWMzIiB+ICJzbWFsbDQiLAogICAgICBpbmQxID09ICJsc2ljNSIgfiAic21hbGw2IiwKICAgICAgaW5kMSA9PSAibHNpYzkiIH4gInNtYWxsOCIsCiAgICAgIGluZDEgPT0gImxzaWMxMCIgfiAic21hbGw5IiwKICAgICAgaW5kMSA9PSAibHNpYzExIiB+ICJzbWFsbDEwIiwKICAgICAgaW5kMSA9PSAiTDEiIH4gImxhcmdlMSIsCiAgICAgIGluZDEgPT0gIkwyIiB+ICJsYXJnZTIiLAogICAgICBpbmQxID09ICJMMyIgfiAibGFyZ2UzIiwKICAgICAgaW5kMSA9PSAibHNpYzEiIH4gImxhcmdlNCIsCiAgICAgIGluZDEgPT0gImxzaWMyIiB+ICJsYXJnZTUiLAogICAgICBpbmQxID09ICJsc2ljNyIgfiAibGFyZ2U2IiwKICAgICAgaW5kMSA9PSAibHNpYzgiIH4gImxhcmdlNyIpLAogICAgaW5kMiA9IGNhc2Vfd2hlbigKICAgICAgaW5kMiA9PSAiUzEiIH4gInNtYWxsMSIsCiAgICAgIGluZDIgPT0gIlMzIiB+ICJzbWFsbDMiLAogICAgICBpbmQyID09ICJsc2ljMyIgfiAic21hbGw0IiwKICAgICAgaW5kMiA9PSAibHNpYzUiIH4gInNtYWxsNiIsCiAgICAgIGluZDIgPT0gImxzaWM5IiB+ICJzbWFsbDgiLAogICAgICBpbmQyID09ICJsc2ljMTAiIH4gInNtYWxsOSIsCiAgICAgIGluZDIgPT0gImxzaWMxMSIgfiAic21hbGwxMCIsCiAgICAgIGluZDIgPT0gIkwxIiB+ICJsYXJnZTEiLAogICAgICBpbmQyID09ICJMMiIgfiAibGFyZ2UyIiwKICAgICAgaW5kMiA9PSAiTDMiIH4gImxhcmdlMyIsCiAgICAgIGluZDIgPT0gImxzaWMxIiB+ICJsYXJnZTQiLAogICAgICBpbmQyID09ICJsc2ljMiIgfiAibGFyZ2U1IiwKICAgICAgaW5kMiA9PSAibHNpYzciIH4gImxhcmdlNiIsCiAgICAgIGluZDIgPT0gImxzaWM4IiB+ICJsYXJnZTciKSwKICAgICdjb21wYXJpc29uJyA9IGNhc2Vfd2hlbigKICAgICAgc3RyX2RldGVjdChpbmQxLCBwYXR0ZXJuID0gImxhcmdlIikgJiBzdHJfZGV0ZWN0KGluZDIsIHBhdHRlcm4gPSAibGFyZ2UiKSB+ICJ3aXRoaW4iLAogICAgICBzdHJfZGV0ZWN0KGluZDEsIHBhdHRlcm4gPSAic21hbGwiKSAmIHN0cl9kZXRlY3QoaW5kMiwgcGF0dGVybiA9ICJzbWFsbCIpIH4gIndpdGhpbiIsIAogICAgICBzdHJfZGV0ZWN0KGluZDEsIHBhdHRlcm4gPSAibGFyZ2UiKSAmIHN0cl9kZXRlY3QoaW5kMiwgcGF0dGVybiA9ICJzbWFsbCIpIH4gImFjcm9zcyIsCiAgICAgIHN0cl9kZXRlY3QoaW5kMSwgcGF0dGVybiA9ICJzbWFsbCIpICYgc3RyX2RldGVjdChpbmQyLCBwYXR0ZXJuID0gImxhcmdlIikgfiAiYWNyb3NzIgogICAgKSkgCgpnZ3Bsb3QoaW5kX2Rpc3QsIGFlcyhkaXN0LCBmaWxsID0gY29tcGFyaXNvbikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuMDA1KSArIAogIGxhYnMoeCA9ICJEaXN0YW5jZSIpICsgCiAgdGhlbWVfbWF0dCgpCmBgYAoKCmBgYHtyfQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyIpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBncm91cF9ieShjb2xsZWN0aW9uX2RhdGUpICU+JSAKICBtdXRhdGUoc2l6ZV9jZW50ZXIgPSBzY2FsZShzaXplLCBjZW50ZXIgPSBULCBzY2FsZSA9IEYpKSAlPiUgCiAgZ2dwbG90KGFlcyh5ID0gY29sbGVjdGlvbl9kYXRlLCB4ID0gc2l6ZSwgZmlsbCA9IGNvbGxlY3Rpb25fdGVtcCkpICsgCiAgZmFjZXRfd3JhcChzZXh+LikgKyAKICBnZW9tX2RlbnNpdHlfcmlkZ2VzKGJhbmR3aWR0aCA9IDAuMDQpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMC44OSkgKyAKICBsYWJzKHggPSAiU2l6ZSAobW0pIiwKICAgICAgIHkgPSAiRGF0ZSIsIAogICAgICAgZmlsbCA9ICJDb2xsLiBUZW1wLiAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQpgYGAKCmBgYHtyfQpmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc3BfbmFtZSA9PSAiTGVwdG9kaWFwdG9tdXMgbWludXR1cyIpICU+JSAKICBmaWx0ZXIoc2V4ICE9ICJqdXZlbmlsZSIpICU+JSAKICBnZ3Bsb3QoYWVzKHkgPSBjb2xsZWN0aW9uX2RhdGUsIHggPSBzaXplLCBmaWxsID0gY29sbGVjdGlvbl90ZW1wKSkgKyAKICBmYWNldF93cmFwKHNleH4uKSArIAogIGdlb21fZGVuc2l0eV9yaWRnZXMoYmFuZHdpZHRoID0gMC4wNCkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwLjY5KSArIAogIGxhYnMoeCA9ICJTaXplIChtbSkiLAogICAgICAgeSA9ICJEYXRlIiwgCiAgICAgICBmaWxsID0gIkNvbGwuIFRlbXAuICjCsEMpIikgKyAKICBjb29yZF9jYXJ0ZXNpYW4oeGxpbSA9IGMoMC41LDAuOSkpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQpgYGAKCiMjIERpc3RyaWJ1dGlvbiBMYWcgTm9uLUxpbmVhciBNb2RlbCAoRExOTSBhcHByb2FjaCkgCmBgYHtyfQpkbG5tX2RhdGEgPSBmdWxsX2RhdGEgJT4lICAKICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgc2VsZWN0KGNvbGxlY3Rpb25fZGF0ZSwgZGF5c19pbl9sYWIsIGNvbGxlY3Rpb25fdGVtcCwgcmVwbGljYXRlLCBzcF9uYW1lLCBzaXplLCBmZWN1bmRpdHksIGN0bWF4KSAlPiUgCiAgZ3JvdXBfYnkoY29sbGVjdGlvbl9kYXRlLCBjb2xsZWN0aW9uX3RlbXAsIHNwX25hbWUpICU+JSAgCiAgc3VtbWFyaXNlKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4LCBuYS5ybSA9IFQpLAogICAgICAgICAgICBtZWFuX3NpemUgPSBtZWFuKHNpemUsIG5hLnJtID0gVCksCiAgICAgICAgICAgIHNhbXBsZSA9IG4oKSkKYGBgCgpgYGB7cn0KaG91cmx5X3RlbXBzID0gcmF3X3RlbXBzICU+JSAgCiAgbXV0YXRlKGhvdXIgPSBsdWJyaWRhdGU6OmhvdXIoZGF0ZVRpbWUpKSAlPiUgIAogIGdyb3VwX2J5KGRhdGUsIGhvdXIpICU+JSAgCiAgc3VtbWFyaXNlKG1lYW5fdGVtcCA9IG1lYW4oZGVnQykpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGNvbXBsZXRlKGRhdGUsIG5lc3RpbmcoaG91cikpICU+JSAgCiAgbXV0YXRlKHRpbWVzdGVwID0geW1kX2htcygKICAgIHBhc3RlKGx1YnJpZGF0ZTo6YXNfZGF0ZShkYXRlKSwgCiAgICAgICAgICBwYXN0ZTAoaG91ciwgIjowMDowMCIpLCBzZXAgPSAiICIpKSwKICAgIG9ic2VydmF0aW9uID0gcm93X251bWJlcigpKSAKCmBgYAoKYGBge3J9CmlmKHByZWRpY3RfdnVsbiA9PSBGKXsKICBrbml0cjo6a25pdF9leGl0KCkKfQpgYGAKCgojIyBQcmVkaWN0aW5nIFZ1bG5lcmFiaWxpdHkgClVzaW5nIHRoZSBvYnNlcnZlZCB0aGVybWFsIGxpbWl0IGRhdGEsIHdlIGNhbiBwcm9kdWNlIGEgaGluZGNhc3Qgb2YgdGhlcm1hbCBzdHJlc3MgZm9yIExha2UgQ2hhbXBsYWluIGNvcGVwb2RzLiBGb3IgdGhlc2UgaW5pdGlhbCBhc3NheXMsIHdlIHdpbGwgZGVmaW5lIHRoZXJtYWwgc3RyZXNzIGFzIGFueSB0aW1lIHdoZW4gbWF4aW11bSBkYWlseSB3YXRlciB0ZW1wZXJhdHVyZSBpcyB3aXRoaW4gMsKwQyBvZiBjb3BlcG9kIENUbWF4IG9yIGhpZ2hlci4gV2Ugd2lsbCB1c2UgdGhyZWUgZGlmZmVyZW50IHNjZW5hcmlvczogMSkgdGhlIGF2ZXJhZ2UgQ1RtYXggZm9yIGVhY2ggc3BlY2llcywgMikgQ1RtYXggcHJlZGljdGVkIHVzaW5nIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmVzLCBhbmQgMykgZm9yIHNwZWNpZXMgdGhhdCBoYXZlIHN1ZmZpY2llbnQgZGF0YSwgQ1RtYXggcHJlZGljdGVkIHVzaW5nIHdoaWNoZXZlciBlbnZpcm9ubWVudGFsIGZhY3RvciBpcyB0aGUgc3Ryb25nZXN0IGNhbmRpZGF0ZSBmb3IgZHJpdmluZyBhY2NsaW1hdGlvbi4gSW4gYWxsIGNhc2VzLCBkYXRhIGlzIGZpbHRlcmVkIHRvIGp1c3QgdGhlcm1hbCBsaW1pdHMgb2YgYWR1bHQgZmVtYWxlcy4gCgojIyMgU2NlbmFyaW8gMQpgYGB7cn0KbWVhbl9jdG1heCA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNleCA9PSAiZmVtYWxlIikgJT4lICAKICBncm91cF9ieShzcF9uYW1lKSAlPiUgCiAgc3VtbWFyaXplKCJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpKSAlPiUgCiAgYXJyYW5nZShtZWFuX2N0bWF4KQoKa25pdHI6OmthYmxlKG1lYW5fY3RtYXgpCmBgYAoKYGBge3J9CiMgIyBDb25zdHJ1Y3RzIHRoZSBVUkwgZm9yIHRoZSBmdWxsIHRlbXBlcmF0dXJlIGRhdGEgc2V0OyBSVU4gVEhJUyBPTkNFCiMgaGluZF91cmwgPSBjb25zdHJ1Y3ROV0lTVVJMKHNpdGVOdW1iZXJzID0gc2l0ZU51bWJlciwgcGFyYW1ldGVyQ2QgPSBwYXJhbWV0ZXJDZCwgc2VydmljZSA9ICJ1diIpCiMgCiMgaGluZF90ZW1wX2RhdGEgPSBpbXBvcnRXYXRlck1MMShoaW5kX3VybCwgYXNEYXRlVGltZSA9IFQpICU+JQojICAgbXV0YXRlKCJkYXRlIiA9IGFzLkRhdGUoZGF0ZVRpbWUpKSAlPiUKIyAgIHNlbGVjdChkYXRlLCAidGVtcCIgPSBYXzAwMDEwXzAwMDAwKQojIAojIHdyaXRlLnRhYmxlKHggPSBoaW5kX3RlbXBfZGF0YSwgZmlsZSA9ICJoaW5kY2FzdF90ZW1wcy5jc3YiLCByb3cubmFtZXMgPSBGLCBzZXAgPSAiLCIpCmBgYAoKYGBge3J9CiMgZ2dwbG90KGhpbmRfdGVtcF9kYXRhLCBhZXMoeCA9IGRhdGUsIHkgPSB0ZW1wKSkgKyAKIyAgIGdlb21fbGluZShsaW5ld2lkdGggPSAwLjEpICsgCiMgICBsYWJzKHggPSAiRGF0ZSIsIAojICAgICAgICB5ID0gIldhdGVyIFRlbXBlcmF0dXJlICjCsEMpIikgKwojICAgdGhlbWVfbWF0dCgpCmBgYAoKSW4gdGhlIHNpbXBsZXN0IHNjZW5hcmlvLCBzcGVjaWVzIHRoZXJtYWwgbGltaXRzIGFyZSBzdGF0aWMgdGhyb3VnaCB0aW1lLCByZXByZXNlbnRlZCBieSB0aGUgYXZlcmFnZSBDVG1heCBvZiBhZHVsdCBmZW1hbGUgY29wZXBvZHMuIEluIHRoaXMgc2NlbmFyaW8sIG9ubHkgdGhyZWUgb2YgdGhlIHNldmVuIG9ic2VydmVkIHNwZWNpZXMgYXJlIGV4cG9zZWQgdG8gdGhlcm1hbCBzdHJlc3MgKHRlbXBlcmF0dXJlcyB3aXRoaW4gNcKwQyBvZiBDVG1heCkuIFRlbXBlcmF0dXJlcyBhcHByb2FjaGVkIHRoZSB0aGVybWFsIGxpbWl0IG9mICpMZXB0b2RpYXB0b211cyBzaWNpbGlzKiBvbiBhIGhhbmRmdWwgb2YgZGF5cy4gQnkgY29udHJhc3QsICpTZW5lY2VsbGEgY2FsYW5vaWRlcyogYW5kICpMaW1ub2NhbGFudXMgbWFjcnVydXMqIHdlcmUgYm90aCBleHBvc2VkIHRvIHN1YnN0YW50aWFsIHRoZXJtYWwgc3RyZXNzIHRocm91Z2hvdXQgYSBsYXJnZSBwb3J0aW9uIG9mIHRoZSB5ZWFyLCBsaWtlbHkgZXhwbGFpbmluZyB3aHkgdGhlc2Ugc3BlY2llcyBhcmUgYWJzZW50IGZyb20gdGhlIGNvbW11bml0eSBmb3IgdGhlIHN1bW1lciBhbmQgZmFsbCBwZXJpb2RzLiAKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQpoaW5kMV9kYXRhID0gaGluZF90ZW1wX2RhdGEgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpemUoImRhaWx5X21heCIgPSBtYXgodGVtcCksCiAgICAgICAgICAgICJkYWlseV9tZWFuIiA9IG1lYW4odGVtcCksKSAlPiUgCiAgYmluZF9jb2xzKHBpdm90X3dpZGVyKG1lYW5fY3RtYXgsIG5hbWVzX2Zyb20gPSBzcF9uYW1lLCB2YWx1ZXNfZnJvbSA9IG1lYW5fY3RtYXgpKSAlPiUgIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSwgLWRhaWx5X21heCwgLWRhaWx5X21lYW4pLAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzcGVjaWVzIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJtZWFuX2N0bWF4IikgJT4lICAKICBtdXRhdGUobGltX2RpZmYgPSBtZWFuX2N0bWF4IC0gZGFpbHlfbWF4KSAlPiUgIAogIG11dGF0ZShkb3kgPSB5ZGF5KGRhdGUpLAogICAgICAgICAibWV0aG9kIiA9ICJOb19hY2NsaW1hdGlvbiIpCgpoaW5kX2RhaWx5X3RlbXBfZGF0YSA9IGhpbmRfdGVtcF9kYXRhICU+JQogIHVuZ3JvdXAoKSAlPiUgCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIAogIHN1bW1hcmlzZShtZWFuX3RlbXAgPSBtZWFuKHRlbXApLAogICAgICAgICAgICBtZWRfdGVtcCA9IG1lZGlhbih0ZW1wKSwKICAgICAgICAgICAgdmFyX3RlbXAgPSB2YXIodGVtcCksIAogICAgICAgICAgICBtaW5fdGVtcCA9IG1pbih0ZW1wKSwgCiAgICAgICAgICAgIG1heF90ZW1wID0gbWF4KHRlbXApKSAlPiUgCiAgbXV0YXRlKCJyYW5nZV90ZW1wIiA9IG1heF90ZW1wIC0gbWluX3RlbXApCgojdGFibGUoaGluZDFfZGF0YSRzcGVjaWVzKQoKaGluZDFfZGF0YSAlPiUgCiAgZmlsdGVyKGxpbV9kaWZmIDw9IDUpICU+JSAgCiAgZ2dwbG90KGFlcyh4ID0gZG95LCB5ID0gbGltX2RpZmYsIGNvbG91ciA9IHNwZWNpZXMpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCAKICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZ2VvbV9zbW9vdGgoc2UgPSBGKSArIAogIGxhYnMoeCA9ICJEYXkgb2YgWWVhciIsIAogICAgICAgeSA9ICJQcmVkaWN0ZWQgV2FybWluZyBUb2xlcmFuY2UgXG4owrBDIEFib3ZlIERhaWx5IE1heCkiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKIyMjIFNjZW5hcmlvIDIKSW4gdGhlIHNlY29uZCBzY2VuYXJpbywgdGhlcm1hbCBsaW1pdHMgdmFyeSB3aXRoaW4gYW5kIGJldHdlZW4gc3BlY2llcy4gQSBzaW1wbGUgbW9kZWwgaXMgdXNlZCB0byBwcmVkaWN0IHNwZWNpZXMgdGhlcm1hbCBsaW1pdHMgYmFzZWQgb24gbWVhbiBkYWlseSB0ZW1wZXJhdHVyZSAoQ1RtYXggYXMgYSBmdW5jdGlvbiBvZiBzcGVjaWVzIGFuZCBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLCBidXQgd2l0aG91dCB0aGUgaW50ZXJhY3Rpb24gYmV0d2VlbiB0aGVzZSB0d28gZmFjdG9ycykuIFRoZXNlIHByZWRpY3RlZCB0aGVybWFsIGxpbWl0cyBhcmUgdGhlbiBjb21wYXJlZCBhZ2FpbnN0IHRoZSBtYXhpbXVtIGRhaWx5IHRlbXBlcmF0dXJlIHRvIGVzdGltYXRlIHRoZXJtYWwgc3RyZXNzLCBhcyBpbiBTY2VuYXJpbyAxLiBJbmNsdWRpbmcgdGhpcyBzaW1wbGUgZm9ybSBvZiBhY2NsaW1hdGlvbiBpbiB0aGUgbW9kZWwgcmVkdWNlZCB0aGUgZGVncmVlIG9mIHRoZXJtYWwgc3RyZXNzIGZvciBlYWNoIHNwZWNpZXMsIGVsaW1pbmF0aW5nIGl0IGVudGlyZWx5IGZvciAqTGVwdG9kaWFwdG9tdXMgc2ljaWxpcyouIE5vdGUgdGhhdCB0aGUgbWFnbml0dWRlIG9mIHRoZSBwcmVkaWN0ZWQgc3RyZXNzIGlzICBsb3cgZW5vdWdoIHRoYXQgcmVtb3ZpbmcgdGhlIDXCsEMgYnVmZmVyIGFyb3VuZCB0aGUgcHJlZGljdGVkIHRoZXJtYWwgbGltaXRzIHdvdWxkIGFjdHVhbGx5IGxpbWl0IHByZWRpY3RlZCB0aGVybWFsIHN0cmVzcyB0byBqdXN0IGEgZmV3IGRheXMgZm9yICpTZW5lY2VsbGEgY2FsYW5vaWRlcyouIAoKYGBge3IgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTB9CmhpbmRjYXN0X21vZGVsMSA9IGxtKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBzZXggPT0gImZlbWFsZSIpLAogICAgICAgICAgICAgICAgICAgICBjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCArIHNwX25hbWUpCgpoaW5kMl9kYXRhID0gaGluZF90ZW1wX2RhdGEgJT4lIAogIGdyb3VwX2J5KGRhdGUpICU+JSAKICBzdW1tYXJpemUoImNvbGxlY3Rpb25fdGVtcCIgPSBtZWFuKHRlbXApLAogICAgICAgICAgICAiZGFpbHlfbWF4IiA9IG1heCh0ZW1wKSkgJT4lIAogIGJpbmRfY29scygKICAgIHBpdm90X3dpZGVyKG1lYW5fY3RtYXgsIAogICAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNwX25hbWUsIAogICAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBtZWFuX2N0bWF4KSkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYygtZGF0ZSwgLWRhaWx5X21heCwgLWNvbGxlY3Rpb25fdGVtcCksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInNwX25hbWUiLCAKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIm1lYW5fY3RtYXgiKSAlPiUgCiAgc2VsZWN0KC1tZWFuX2N0bWF4KSAlPiUgCiAgbXV0YXRlKCJwcmVkX2N0bWF4IiA9IHByZWRpY3QubG0gKGhpbmRjYXN0X21vZGVsMSwgbmV3ZGF0YSA9IC4pKSAlPiUgCiAgc2VsZWN0KGRhdGUsICJkYWlseV9tZWFuIiA9IGNvbGxlY3Rpb25fdGVtcCwgZGFpbHlfbWF4LCAic3BlY2llcyIgPSBzcF9uYW1lLCBwcmVkX2N0bWF4KSAlPiUgCiAgbXV0YXRlKGxpbV9kaWZmID0gcHJlZF9jdG1heCAtIGRhaWx5X21heCkgJT4lIAogICNmaWx0ZXIobGltX2RpZmYgPD0gMCkgJT4lICAKICBtdXRhdGUoZG95ID0geWRheShkYXRlKSwKICAgICAgICAgIm1ldGhvZCIgPSAiQ29uc3RhbnRfYWNjbGltYXRpb24iKQoKIyBnZ3Bsb3QoaGluZDJfZGF0YSwgYWVzKHggPSBkYWlseV9tZWFuLCB5ID0gcHJlZF9jdG1heCwgY29sb3VyID0gc3BlY2llcykpICsKIyAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpIAoKIyB0YWJsZShoaW5kMl9kYXRhJHNwZWNpZXMpCmhpbmQyX2RhdGEgJT4lICAKICBmaWx0ZXIobGltX2RpZmYgPD0gNSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBkb3ksIHkgPSBsaW1fZGlmZiwgY29sb3VyID0gc3BlY2llcykpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDUsIAogICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjUpICsKICBnZW9tX3Ntb290aCgpICsgCiAgbGFicyh4ID0gIkRheSBvZiBZZWFyIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCBXYXJtaW5nIFRvbGVyYW5jZSBcbijCsEMgQWJvdmUgRGFpbHkgTWF4KSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgojIyMgU2NlbmFyaW8gMwpUaGUgZmluYWwgc2NlbmFyaW8gYWxsb3dzIHRoZSBlbnZpcm9ubWVudGFsIHZhcmlhYmxlIHVzZWQgdG8gcHJlZGljdCBDVG1heCB0byB2YXJ5IGJldHdlZW4gc3BlY2llcy4gRm9yIHNwZWNpZXMgb2JzZXJ2ZWQgaW4gZmV3ZXIgdGhhbiA1IGNvbGxlY3Rpb25zLCB3ZSB1c2UgdGhlIHNhbWUgYXBwcm9hY2ggYXMgaW4gU2NlbmFyaW8gMi4gRm9yIHNwZWNpZXMgb2JzZXJ2ZWQgaW4gbW9yZSB0aGFuIDUgY29sbGVjdGlvbnMsIGhvd2V2ZXIsIHRoZSBmYWN0b3Igd2l0aCB0aGUgc3Ryb25nZXN0IGNvcnJlbGF0aW9uIHdpdGggQ1RtYXggaXMgdXNlZCB0byBwcmVkaWN0IHRoZXJtYWwgbGltaXRzLiBUaGVzZSBmYWN0b3JzIGFyZSBpbmNsdWRlZCBiZWxvdy4KCmBgYHtyfQpoaW5kX3ByZWRzID0gY29ycl92YWxzICU+JSAgCiAgZmlsdGVyKHNpZyA9PSAiU2lnLiIpICU+JSAKICBkcm9wX25hKGNvcnJlbGF0aW9uKSAlPiUgCiAgZ3JvdXBfYnkoc3BfbmFtZSkgJT4lCiAgYXJyYW5nZShkZXNjKGNvcnJlbGF0aW9uKSkgJT4lIAogIHNsaWNlX2hlYWQobiA9IDEpICU+JSAKICBzZWxlY3QoIlNwZWNpZXMiID0gc3BfbmFtZSwgIlByZWRpY3RvciIgPSBwYXJhbWV0ZXIsICJEdXJhdGlvbiIgPSBkdXJhdGlvbiwgIkNvcnJlbGF0aW9uIiA9IGNvcnJlbGF0aW9uLCAiUC1WYWx1ZSIgPSBwLnZhbHVlKQoKa25pdHI6OmthYmxlKGhpbmRfcHJlZHMsIGFsaWduID0gImMiKQpgYGAKCmBgYHtyfQpoaW5kM19kYXRhID0gaGluZDJfZGF0YSAlPiUgIyBDb250YWlucyBkYXRhIGZvciBzcGVjaWVzIHRoYXQgd29uJ3QgY2hhbmdlIGZyb20gc2NlbmFyaW8gMgogIGZpbHRlcighKHNwZWNpZXMgJWluJSBjb3JyX3ZhbHMkc3BfbmFtZSkpCgpwcmVkc190b19wdWxsID0gaGluZF9wcmVkcyAlPiUgIAogIHNlbGVjdChTcGVjaWVzLCBQcmVkaWN0b3IsIER1cmF0aW9uKSAKCmZvcihpIGluIDE6bGVuZ3RoKHByZWRzX3RvX3B1bGwkU3BlY2llcykpewogIAogIGlmKHByZWRzX3RvX3B1bGwkRHVyYXRpb25baV0gPT0gInByaW9yIil7ICNUaGUgcHJpb3IgZGF5IHRlbXBlcmF0dXJlIG1ldHJpY3Mgc2hvdWxkIGJlIHVzZWQKICAgIGR1cmF0aW9uID0gTkEKICAgIAogICAgcHJlZGljdG9ycyA9IGhpbmRfZGFpbHlfdGVtcF9kYXRhICU+JSAKICAgICAgbXV0YXRlKGRhdGUgPSBkYXRlICsgMSkgCiAgICAKICAgIHBhcmFtZXRlciA9IHByZWRzX3RvX3B1bGwkUHJlZGljdG9yW2ldCiAgICAKICAgIG1vZGVsX2RhdGEgPSBmdWxsX2RhdGEgJT4lCiAgICAgIGZpbHRlcihzcF9uYW1lICVpbiUgcHJlZHNfdG9fcHVsbCRTcGVjaWVzW2ldKSAlPiUgCiAgICAgIGZpbHRlcihzZXggPT0gImZlbWFsZSIpICU+JSAKICAgICAgbXV0YXRlKGNvbGxlY3Rpb25fZGF0ZSA9IGFzX2RhdGUoY29sbGVjdGlvbl9kYXRlKSkgJT4lIAogICAgICBpbm5lcl9qb2luKHByZWRpY3RvcnMsIGpvaW5fYnkoY29sbGVjdGlvbl9kYXRlID09IGRhdGUpKSAlPiUgIAogICAgICBzZWxlY3QoY3RtYXgsIGNvbnRhaW5zKHBhcmFtZXRlcikpCiAgICAKICAgIGlmKGRpbShtb2RlbF9kYXRhKVsyXSA9PSAyKXsKICAgICAgaGluZC5tb2RlbCA9IGxtKGRhdGEgPSBtb2RlbF9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgIGN0bWF4IH4gLikKICAgICAgCiAgICAgIHNwX2RhdGEgPSBwcmVkaWN0b3JzICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgY29udGFpbnMocGFyYW1ldGVyKSkgJT4lIAogICAgICAgIG11dGF0ZShwcmVkX2N0bWF4ID0gcHJlZGljdChoaW5kLm1vZGVsLCBuZXdkYXRhID0gLikpICU+JSAgCiAgICAgICAgc2VsZWN0KGRhdGUsIHByZWRfY3RtYXgpICU+JSAKICAgICAgICBpbm5lcl9qb2luKGhpbmRfZGFpbHlfdGVtcF9kYXRhLCBieSA9IGMoImRhdGUiKSkgJT4lIAogICAgICAgIG11dGF0ZSgic3BlY2llcyIgPSBwcmVkc190b19wdWxsJFNwZWNpZXNbaV0sCiAgICAgICAgICAgICAgICJkb3kiID0geWRheShkYXRlKSwKICAgICAgICAgICAgICAgbGltX2RpZmYgPSBwcmVkX2N0bWF4IC0gbWF4X3RlbXApICU+JSAKICAgICAgICBzZWxlY3QoZGF0ZSwgZGFpbHlfbWVhbiA9IG1lYW5fdGVtcCwgZGFpbHlfbWF4ID0gbWF4X3RlbXAsIHNwZWNpZXMsIHByZWRfY3RtYXgsIGxpbV9kaWZmLCBkb3kpCiAgICAgIAogICAgICBoaW5kM19kYXRhID0gYmluZF9yb3dzKGhpbmQzX2RhdGEsIHNwX2RhdGEpCiAgICB9ZWxzZXsKICAgICAgcHJpbnQoIlRvbyBtYW55IGNvbHVtbnMgc2VsZWN0ZWQiKQogICAgfQogICAgCiAgICAKICB9ZWxzZXsKICAgIGR1cmF0aW9uID0gYXMubnVtZXJpYyhwcmVkc190b19wdWxsJER1cmF0aW9uW2ldKQogIH0KICAKICBpZihwcmVkc190b19wdWxsJER1cmF0aW9uW2ldICE9ICJwcmlvciIgJiBpcy5uYShkdXJhdGlvbikpeyAjRGFpbHkgdGVtcGVyYXR1cmVzIHNob3VsZCBiZSB1c2VkLCBhcyBpbiBTY2VuYXJpbyAyCiAgICBzcF9kYXRhID0gaGluZDJfZGF0YSAlPiUgCiAgICAgIGZpbHRlcihzcGVjaWVzID09IHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSkKICAgIAogICAgaGluZDNfZGF0YSA9IGJpbmRfcm93cyhoaW5kM19kYXRhLCBzcF9kYXRhKQogIH0KICAKICBpZihpcy5udW1lcmljKGR1cmF0aW9uKSl7CiAgICAjTmVpdGhlciB0aGUgcHJpb3IgZGF5IG5vciBkYXkgb2YgbWV0cmljcyBzaG91bGQgYmUgdXNlZDsgdXNlIGR1cmF0aW9uIGFzIG5fZGF5cwogICAgCiAgICBwcmVkaWN0b3JzID0gZ2V0X3ByZWRpY3RvcnMoZGFpbHlfdmFsdWVzID0gaGluZF9kYWlseV90ZW1wX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd190ZW1wID0gaGluZF90ZW1wX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5fZGF5cyA9IGR1cmF0aW9uKQogICAgCiAgICBwYXJhbWV0ZXIgPSBwcmVkc190b19wdWxsJFByZWRpY3RvcltpXQogICAgCiAgICBtb2RlbF9kYXRhID0gZnVsbF9kYXRhICU+JQogICAgICBmaWx0ZXIoc3BfbmFtZSAlaW4lIHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSkgJT4lIAogICAgICBmaWx0ZXIoc2V4ID09ICJmZW1hbGUiKSAlPiUgCiAgICAgIG11dGF0ZShjb2xsZWN0aW9uX2RhdGUgPSBhc19kYXRlKGNvbGxlY3Rpb25fZGF0ZSkpICU+JSAKICAgICAgaW5uZXJfam9pbihwcmVkaWN0b3JzLCBqb2luX2J5KGNvbGxlY3Rpb25fZGF0ZSA9PSBkYXRlKSkgJT4lICAKICAgICAgc2VsZWN0KGN0bWF4LCBjb250YWlucyhwYXN0ZSgiZGF5XyIsIHBhcmFtZXRlciwgc2VwID0gIiIpKSkKICAgIAogICAgaWYoZGltKG1vZGVsX2RhdGEpWzJdID09IDIpewogICAgICBoaW5kLm1vZGVsID0gbG0oZGF0YSA9IG1vZGVsX2RhdGEsIAogICAgICAgICAgICAgICAgICAgICAgY3RtYXggfiAuKQogICAgICAKICAgICAgc3BfZGF0YSA9IHByZWRpY3RvcnMgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBjb250YWlucyhwYXJhbWV0ZXIpKSAlPiUgCiAgICAgICAgbXV0YXRlKHByZWRfY3RtYXggPSBwcmVkaWN0KGhpbmQubW9kZWwsIG5ld2RhdGEgPSAuKSkgJT4lICAKICAgICAgICBzZWxlY3QoZGF0ZSwgcHJlZF9jdG1heCkgJT4lIAogICAgICAgIGlubmVyX2pvaW4oaGluZF9kYWlseV90ZW1wX2RhdGEsIGJ5ID0gYygiZGF0ZSIpKSAlPiUgCiAgICAgICAgbXV0YXRlKCJzcGVjaWVzIiA9IHByZWRzX3RvX3B1bGwkU3BlY2llc1tpXSwKICAgICAgICAgICAgICAgImRveSIgPSB5ZGF5KGRhdGUpLAogICAgICAgICAgICAgICBsaW1fZGlmZiA9IHByZWRfY3RtYXggLSBtYXhfdGVtcCkgJT4lIAogICAgICAgIHNlbGVjdChkYXRlLCBkYWlseV9tZWFuID0gbWVhbl90ZW1wLCBkYWlseV9tYXggPSBtYXhfdGVtcCwgc3BlY2llcywgcHJlZF9jdG1heCwgbGltX2RpZmYsIGRveSkKICAgICAgCiAgICAgIGhpbmQzX2RhdGEgPSBiaW5kX3Jvd3MoaGluZDNfZGF0YSwgc3BfZGF0YSkKICAgICAgCiAgICB9ZWxzZXsKICAgICAgcHJpbnQoIlRvbyBtYW55IGNvbHVtbnMgc2VsZWN0ZWQiKQogICAgfQogICAgCiAgfQp9CgpoaW5kM19kYXRhID0gaGluZDNfZGF0YSAlPiUgCiAgbXV0YXRlKCJtZXRob2QiID0gIlZhcmlhYmxlX2FjY2xpbWF0aW9uIikKYGBgCgpUaGlzIHRoaXJkIGFwcHJvYWNoIGRpZCBub3QgYWZmZWN0IHRoZSBwcmVkaWN0ZWQgcGF0dGVybnMgaW4gKkxpbW5vY2FsYW51cyogb3IgKlNlbmVjZWxsYSogKG5laXRoZXIgc3BlY2llcyBoYXMgYmVlbiBvYnNlcnZlZCBpbiBlbm91Z2ggY29sbGVjdGlvbnMgdG8gZXN0aW1hdGUgdGhlIGVmZmVjdHMgb2YgZGlmZmVyZW50IGVudmlyb25tZW50YWwgZmFjdG9ycykuIENoYW5naW5nIHRoZSBhY2NsaW1hdGlvbiBhcHByb2FjaCBkaWQgYWZmZWN0IHBhdHRlcm5zIGluIHRoZXJtYWwgbGltaXRzIGluIHRoZSBvdGhlciBzcGVjaWVzIHRob3VnaC4gVGhlIGZpZ3VyZSBiZWxvdyBzaG93cyBob3cgcHJlZGljdGVkIHdhcm1pbmcgdG9sZXJhbmNlIHZhcmllcyBvdmVyIHRoZSB5ZWFyIGluIHRoZSBzZXZlbiBzcGVjaWVzLCBiYXNlZCBvbiB0aGUgdGhyZWUgZGlmZmVyZW50IHByZWRpY3Rpb24gbWV0aG9kcy4gSW4gZ2VuZXJhbCwgY29uc3RhbnQgdGhlcm1hbCBsaW1pdHMgKHRoZSAnbm8gYWNjbGltYXRpb24nIG1ldGhvZCkgcmVzdWx0ZWQgaW4gbGFyZ2VyIHdhcm1pbmcgdG9sZXJhbmNlIGR1cmluZyB0aGUgd2ludGVyIGFuZCBsb3dlciB3YXJtaW5nIHRvbGVyYW5jZSBkdXJpbmcgdGhlIHN1bW1lciwgYWx0aG91Z2ggdGhpcyBlZmZlY3Qgd2FzIHNtYWxsIGluIG1vc3Qgc3BlY2llcy4gICAgIAoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwfQpzeW50aGVzaXMgPSBiaW5kX3Jvd3MoCiAgc2VsZWN0KGhpbmQxX2RhdGEsIGRhdGUsIGRveSwgZGFpbHlfbWVhbiwgZGFpbHlfbWF4LCBzcGVjaWVzLCAicHJlZF9jdG1heCIgPSBtZWFuX2N0bWF4LCBsaW1fZGlmZiwgbWV0aG9kKSwKICBzZWxlY3QoaGluZDJfZGF0YSwgZGF0ZSwgZG95LCBkYWlseV9tZWFuLCBkYWlseV9tYXgsICBzcGVjaWVzLCBwcmVkX2N0bWF4LCBsaW1fZGlmZiwgbWV0aG9kKSwKICBzZWxlY3QoaGluZDNfZGF0YSwgZGF0ZSwgZG95LCBkYWlseV9tZWFuLCBkYWlseV9tYXgsICBzcGVjaWVzLCBwcmVkX2N0bWF4LCBsaW1fZGlmZiwgbWV0aG9kKSkgJT4lIAogIG11dGF0ZShtZXRob2QgPSBmY3RfcmVsZXZlbChtZXRob2QsICJOb19hY2NsaW1hdGlvbiIsICJDb25zdGFudF9hY2NsaW1hdGlvbiIsICJWYXJpYWJsZV9hY2NsaW1hdGlvbiIpKQoKY2xpbWF0b2xvZ3kgPSBzeW50aGVzaXMgJT4lIAogIGdyb3VwX2J5KHNwZWNpZXMsIGRveSwgbWV0aG9kKSAlPiUgIAogIHN1bW1hcmlzZSgibWVhbl9kaWZmIiA9IG1lYW4obGltX2RpZmYpLAogICAgICAgICAgICAibWluX2RpZmYiID0gbWluKGxpbV9kaWZmKSwKICAgICAgICAgICAgIm1heF9kaWZmIiA9IG1heChsaW1fZGlmZikpICU+JSAKICBtdXRhdGUobWV0aG9kID0gZmN0X3JlbGV2ZWwobWV0aG9kLCAiTm9fYWNjbGltYXRpb24iLCAiQ29uc3RhbnRfYWNjbGltYXRpb24iLCAiVmFyaWFibGVfYWNjbGltYXRpb24iKSkKCmFjY19lZmZlY3RzID0gc3ludGhlc2lzICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyhkYXRlLCBzcGVjaWVzLCBkb3kpLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gbWV0aG9kLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGxpbV9kaWZmKSAlPiUgIAogIG11dGF0ZSgiY29uc3RfYWNjX2VmZmVjdCIgPSBDb25zdGFudF9hY2NsaW1hdGlvbiAtIE5vX2FjY2xpbWF0aW9uLAogICAgICAgICAidmFyX2FjY19lZmZlY3QiID0gVmFyaWFibGVfYWNjbGltYXRpb24gLSBOb19hY2NsaW1hdGlvbikKCmdncGxvdChzeW50aGVzaXMsIGFlcyh4ID0gZG95LCB5ID0gbGltX2RpZmYsIGNvbG91ciA9IG1ldGhvZCkpICsgCiAgZmFjZXRfd3JhcChzcGVjaWVzfi4pICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMSkgKyAKICBsYWJzKHggPSAiRGF5IG9mIFllYXIiLCAKICAgICAgIHkgPSAiUHJlZGljdGVkIFdhcm1pbmcgVG9sZXJhbmNlICjCsEMgQWJvdmUgRGFpbHkgTWF4KSIpICsgCiAgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KGFscGhhID0gMSkpKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKGJhc2Vfc2l6ZSA9IDE4KSArIAogIHRoZW1lKHN0cmlwLnRleHQueC50b3AgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKYGBgCgpgYGB7ciwgaW5jbHVkZSA9IEZ9CnllYXJseV9zdW1tYXJ5ID0gc3ludGhlc2lzICU+JSAgCiAgbXV0YXRlKCJ5ZWFyIiA9IHllYXIoZGF0ZSkpICU+JSAKICBncm91cF9ieShzcGVjaWVzLCB5ZWFyLCBtZXRob2QpICU+JSAKICBzdW1tYXJpc2UoIm1pbl93dCIgPSBtaW4obGltX2RpZmYpLAogICAgICAgICAgICAibWF4X3d0IiA9IG1heChsaW1fZGlmZikpICU+JSAKICBwaXZvdF9sb25nZXIoY29scyA9IGMobWluX3d0LCBtYXhfd3QpLCAKICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAibWV0cmljIiwgCiAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJ3dCIpCgpnZ3Bsb3QoeWVhcmx5X3N1bW1hcnksIGFlcyh4ID0gbWV0aG9kLCB5ID0gd3QsIGNvbG91ciA9IG1ldHJpYykpICsgCiAgZmFjZXRfd3JhcCgufnNwZWNpZXMpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKYGBgCgo=